polylib 7.01
arithmetique.h
Go to the documentation of this file.
1/* header file built by cproto */
2#ifndef arithmetique_header_included
3#define arithmetique_header_included
4
5/** package arithmetique
6 *
7 * $Id: arithmetique.h,v 1.24 2007/02/22 09:16:57 skimo Exp $
8 *
9 * Francois Irigoin, mai 1989
10 *
11 * Modifications
12 * - rewrite of DIVIDE which was wrong (Remi Triolet, Francois Irigoin,
13 * april 90)
14 * - simplification of POSITIVE_DIVIDE by suppressing one modulo
15 * - B.Meister : added addmul, operation existing in gmp and quite useful
16 * (05-2005)
17 */
18
19/* We would like linear to be generic about the "integer" type used
20 * to represent integer values. Thus Value is defined here. It should
21 * be changed to "int" "long" or "long long". In an ideal world,
22 * any source modification should be limited to this package.
23 *
24 * Indeed, we cannot switch easily to bignums that need constructors
25 * dans destructors... That would lead to too many modifications...
26 * C++ would make things easier and cleaner...
27 *
28 * Fabien COELHO
29 */
30
31#include <limits.h> /* Included for getting constants: INT_MAX, etc.. */
32#include <stdio.h>
33
34#ifdef GNUMP
35#include <gmp.h>
36#include <stdlib.h>
37#include <string.h>
38#ifndef mp_get_memory_functions
39#if defined(__cplusplus)
40extern "C" {
41#endif
42void mp_get_memory_functions(void *(**alloc_func_ptr)(size_t),
43 void *(**realloc_func_ptr)(void *, size_t, size_t),
44 void (**free_func_ptr)(void *, size_t));
45#if defined(__cplusplus)
46}
47#endif
48#endif
49#endif
50
51#ifdef CLN
52#include <sstream>
53#define WANT_OBFUSCATING_OPERATORS
54#include <cln/cln.h>
55#endif
56
57/*
58 * Constants like LONG_LONG_MAX are not defined with ansi options, so they are
59 * defined here.
60 */
61
62#ifndef LONG_LONG_MAX
63
64/* would fix on solaris:
65 * #define LONG_LONG_MAX LLONG_MAX
66 * #define LONG_LONG_MIN LLONG_MIN
67 */
68
69#ifndef __LONG_LONG_MAX__
70#define __LONG_LONG_MAX__ 9223372036854775807LL
71#endif
72#undef LONG_LONG_MAX
73#define LONG_LONG_MAX __LONG_LONG_MAX__
74#undef LONG_LONG_MIN
75#define LONG_LONG_MIN (-LONG_LONG_MAX - 1)
76#undef ULONG_LONG_MAX
77#define ULONG_LONG_MAX (LONG_LONG_MAX * 2ULL + 1)
78#endif
79
80
81/*
82 # #### # # #### # #### # # ####
83 # # # ## # # # # # # ## # # #
84 # # # # # # # # # # # # # #
85 # # # # # # # ### # # # # # # # ###
86 # # # # ## # # # # # # ## # #
87 ###### #### # # #### ###### #### # # ####
88
89*/
90
91#if defined(LINEAR_VALUE_IS_LONGLONG)
92
93#define LINEAR_VALUE_STRING "long long int"
94typedef long long int Value;
95#if defined(WIN32) && !defined(unix)
96/* Mingw or Windows need an incompatible format string. */
97#define VALUE_FMT "%I64d"
98#else
99#define VALUE_FMT "%lld"
100#endif
101#define VALUE_CONST(val) (val##LL)
102
103/*
104 * CAUTION! 'VALUE_MIN' is defined as 'LONG_LONG_MIN +1' so as to preserve the
105 * symmetry (-min==max) and to have a NAN value. FC
106 */
107
108#define VALUE_NAN LONG_LONG_MIN
109#define VALUE_MIN (LONG_LONG_MIN + 1LL)
110#define VALUE_MAX LONG_LONG_MAX
111#define VALUE_SQRT_MIN long_to_value(LONG_MIN)
112#define VALUE_SQRT_MAX long_to_value(LONG_MAX)
113#define VALUE_ZERO (0LL)
114#define VALUE_ONE (1LL)
115#define VALUE_MONE (-1LL)
116
117#define VALUE_TO_LONG(val) \
118 ((long)((val) > (Value)LONG_MIN && (val) <= (Value)LONG_MAX) \
119 ? (val) \
120 : (THROW(overflow_error), LONG_MIN))
121
122#define VALUE_TO_INT(val) \
123 ((int)((val) > (Value)INT_MIN && (val) <= (Value)INT_MAX) \
124 ? (val) \
125 : (THROW(overflow_error), INT_MIN))
126
127#define VALUE_TO_DOUBLE(val) ((double)(val))
128
129/* #define VALUE_TO_FLOAT(val) ((float)(val)): Doesn't seem to work with gcc */
130#define VALUE_TO_FLOAT(val) ((float)((int)(val)))
131
132/* end LINEAR_VALUE_IS_LONGLONG */
133
134/*
135
136 # #### # # ####
137 # # # ## # # #
138 # # # # # # #
139 # # # # # # # ###
140 # # # # ## # #
141 ###### #### # # ####
142
143*/
144
145#elif defined(LINEAR_VALUE_IS_LONG)
146
147#define LINEAR_VALUE_STRING "long int"
148typedef long Value;
149#define VALUE_FMT "%ld"
150#define VALUE_CONST(val) (val##L)
151#define VALUE_NAN LONG_MIN
152#define VALUE_MIN (LONG_MIN + 1L)
153#define VALUE_MAX LONG_MAX
154#define VALUE_SQRT_MIN int_to_value(INT_MIN)
155#define VALUE_SQRT_MAX int_to_value(INT_MAX)
156#define VALUE_ZERO 0L
157#define VALUE_ONE 1L
158#define VALUE_MONE -1L
159#define VALUE_TO_LONG(val) (val)
160#define VALUE_TO_INT(val) ((int)(val))
161#define VALUE_TO_FLOAT(val) ((float)(val))
162#define VALUE_TO_DOUBLE(val) ((double)(val))
163
164/* end LINEAR_VALUE_IS_LONG */
165
166/*
167 ###### # #### ## #####
168 # # # # # # #
169 ##### # # # # # #
170 # # # # ###### #
171 # # # # # # #
172 # ###### #### # # #
173
174*/
175
176/*
177#elif defined(LINEAR_VALUE_IS_FLOAT)
178
179#define LINEAR_VALUE_STRING "float"
180typedef float Value;
181#define VALUE_FMT "%f"
182#define VALUE_CONST(val) (val)
183#define VALUE_MIN FLOAT_MIN
184#define VALUE_MAX FLOAT_MAX
185#define VALUE_ZERO 0.0
186#define VALUE_ONE 1.0
187#define VALUE_MONE -1.0
188#define VALUE_TO_LONG(val) ((long)(val))
189#define VALUE_TO_INT(val) ((int)(val))
190#define VALUE_TO_FLOAT(val) ((float)(val))
191#define VALUE_TO_DOUBLE(val) ((double)(val))
192
193*/
194
195/* end LINEAR_VALUE_IS_FLOAT */
196
197/*
198 #### # # ## ##### # #
199 # # # # # # # # # #
200 # ###### # # # # #######
201 # # # ###### ##### # #
202 # # # # # # # # # #
203 #### # # # # # #
204
205 */
206
207/* Char version is used to detect invalid assignments */
208
209#elif defined(LINEAR_VALUE_IS_CHARS)
210
211#define LINEAR_VALUE_STRING "char"
212typedef union {
213 char *s;
214 long l;
215 int i;
216 float f;
217 double d;
218} Value;
219#define VALUE_FMT "%s"
220#define VALUE_CONST(val) ((Value)(val))
221#define VALUE_NAN ((Value)(long)0xdadeebee)
222#define VALUE_MIN ((Value)(long)0xdeadbeef)
223#define VALUE_MAX ((Value)(long)0xfeedabee)
224#define VALUE_ZERO ((Value)0)
225#define VALUE_ONE ((Value)1)
226#define VALUE_MONE ((Value) - 1)
227#define VALUE_TO_LONG(val) (val.l)
228#define VALUE_TO_INT(val) (val.i)
229#define VALUE_TO_FLOAT(val) (val.f)
230#define VALUE_TO_DOUBLE(val) (val.d)
231
232/* end LINEAR_VALUE_IS_CHARS */
233
234/*
235 ##### # # ######
236 # # ## ## # #
237 # # # # # # #
238 # #### # # # ######
239 # # # # #
240 # # # # #
241 ##### # # #
242*/
243#elif defined(GNUMP)
244
245#define LINEAR_VALUE_STRING "gmp"
246typedef mpz_t Value;
247#define VALUE_FMT "%s"
248
249/* don't use these, use value_set_si instead ! */
250#undef VALUE_ZERO
251#undef VALUE_ONE
252#undef VALUE_MONE
253#define VALUE_TO_LONG(val) (mpz_get_si(val))
254#define VALUE_TO_INT(val) ((int)mpz_get_si(val))
255#define VALUE_TO_FLOAT(val) ((float)((int)mpz_get_si(val)))
256#define VALUE_TO_DOUBLE(val) (mpz_get_d(val))
257
258/* end GNUMP */
259
260/*
261 ##### # # #
262 # # # ## #
263 # # # # #
264 # # # # #
265 # # # # #
266 # # # # ##
267 ##### ####### # #
268*/
269#elif defined(CLN)
270
271#define LINEAR_VALUE_STRING "cln"
272typedef cln::cl_I Value;
273#define VALUE_FMT "%s"
274
275#define VALUE_TO_INT(val) (cln::cl_I_to_int(val))
276#define VALUE_TO_DOUBLE(val) (cln::double_approx(val))
277
278/* end CLN */
279
280/*
281 # # # #####
282 # ## # #
283 # # # # #
284 # # # # #
285 # # ## #
286 # # # #
287
288*/
289
290// #elif defined(LINEAR_VALUE_IS_INT)
291#else
292
293#define LINEAR_VALUE_STRING "int"
294typedef int Value;
295#define VALUE_FMT "%d"
296#define VALUE_CONST(val) (val)
297#define VALUE_NAN INT_MIN
298#define VALUE_MIN (INT_MIN + 1)
299#define VALUE_MAX INT_MAX
300#define VALUE_ZERO 0
301#define VALUE_ONE 1
302#define VALUE_MONE -1
303#define VALUE_TO_LONG(val) ((long)(val))
304#define VALUE_TO_INT(val) ((int)(val))
305#define VALUE_TO_FLOAT(val) ((float)(val))
306#define VALUE_TO_DOUBLE(val) ((double)(val))
307
308/* end LINEAR_VALUE_IS_INT */
309
310#endif
311/* end LINEAR_VALUE_IS_* */
312
313
314/* ********************************************************************* */
315/* ***************** MACROS FOR MANIPULATING VALUES ******************** */
316/* ********************************************************************* */
317
318/* Starts with library-specific functions: CLN and GMP, and then defaults */
319#if defined(CLN)
320
321#define value_init(val) ((val).word = ((cln::cl_uint)cl_FN_tag) << cl_tag_shift)
322#define value_assign(v1, v2) ((v1) = (v2))
323#define value_set_si(val, i) ((val) = (i))
324#define value_set_double(val, d) ((val) = cln::truncate1(cln::cl_R(d)))
325#define value_clear(val) ((val) = 0)
326#define value_read(val, str) ((val) = (str))
327#define value_print(Dst, fmt, val) \
328 { \
329 std::ostringstream strm; \
330 strm << val; \
331 fprintf((Dst), (fmt), strm.str().c_str()); \
332 }
333#define value_swap(v1, v2) \
334 { \
335 Value tmp; \
336 tmp = v2; \
337 v2 = v1; \
338 v1 = tmp; \
339 }
340
341/* Boolean operators on 'Value' */
342
343#define value_eq(v1, v2) ((v1) == (v2))
344#define value_ne(v1, v2) ((v1) != (v2))
345#define value_gt(v1, v2) ((v1) > (v2))
346#define value_ge(v1, v2) ((v1) >= (v2))
347#define value_lt(v1, v2) ((v1) < (v2))
348#define value_le(v1, v2) ((v1) <= (v2))
349
350#define value_abs_eq(v1, v2) (cln::abs(v1) == cln::abs(v2))
351#define value_abs_ne(v1, v2) (cln::abs(v1) != cln::abs(v2))
352#define value_abs_gt(v1, v2) (cln::abs(v1) > cln::abs(v2))
353#define value_abs_ge(v1, v2) (cln::abs(v1) >= cln::abs(v2))
354#define value_abs_lt(v1, v2) (cln::abs(v1) < cln::abs(v2))
355#define value_abs_le(v1, v2) (cln::abs(v1) <= cln::abs(v2))
356
357#define value_sign(val) (cln::signum(val))
358#define value_cmp(v1, v2) (cln::compare((v1), (v2)))
359
360#define value_addto(ref, val1, val2) ((ref) = (val1) + (val2))
361#define value_add_int(ref, val, vint) ((ref) = (val) + (vint))
362#define value_addmul(ref, val1, val2) ((ref) += (val1) * (val2))
363#define value_increment(ref, val) ((ref) = (val) + 1)
364#define value_multiply(ref, val1, val2) ((ref) = (val1) * (val2))
365#define value_subtract(ref, val1, val2) ((ref) = (val1) - (val2))
366#define value_sub_int(ref, val1, val2) ((ref) = (val1) - (val2))
367#define value_decrement(ref, val) ((ref) = (val) - 1)
368#define value_division(ref, val1, val2) ((ref) = cln::truncate1(val1, val2))
369#define value_divexact(ref, val1, val2) ((ref) = cln::exquo(val1, val2))
370#define value_modulus(ref, val1, val2) \
371 ((ref) = cln::truncate2(val1, val2).remainder)
372#define value_pdivision(ref, val1, val2) ((ref) = cln::floor1(val1, val2))
373#define value_pmodulus(ref, val1, val2) \
374 ((ref) = cln::floor2(val1, val2).remainder)
375#define value_oppose(ref, val) ((ref) = -(val))
376#define value_absolute(ref, val) ((ref) = cln::abs(val))
377#define value_minimum(ref, val1, val2) ((ref) = cln::min((val1), (val2)))
378#define value_maximum(ref, val1, val2) ((ref) = cln::max((val1), (val2)))
379#define value_gcd(ref, val1, val2) ((ref) = cln::gcd((val1), (val2)))
380#define value_lcm(ref, val1, val2) ((ref) = cln::lcm((val1), (val2)))
381#define value_orto(ref, val1, val2) ((ref) = (val1) | (val2))
382#define value_andto(ref, val1, val2) ((ref) = (val1) & (val2))
383
384/* Conditional operations on 'Value' */
385
386#define value_pos_p(val) ((val) > 0)
387#define value_neg_p(val) ((val) < 0)
388#define value_posz_p(val) ((val) >= 0)
389#define value_negz_p(val) ((val) <= 0)
390#define value_zero_p(val) ((val) == 0)
391#define value_notzero_p(val) ((val) != 0)
392#define value_one_p(val) ((val) == 1)
393#define value_notone_p(val) ((val) != 1)
394#define value_mone_p(val) ((val) == -1)
395#define value_notmone_p(val) ((val) != -1)
396#define value_cmp_si(val, n) (cln::compare(val, n))
397
398/* end #if defined(CLN) */
399/* ********************************************************************* */
400#elif defined(GNUMP)
401
402/* Basic macros */
403#define value_init(val) (mpz_init((val)))
404#define value_assign(v1, v2) (mpz_set((v1), (v2)))
405#define value_set_si(val, i) (mpz_set_si((val), (i)))
406#define value_set_double(val, d) (mpz_set_d((val), (d)))
407#define value_clear(val) (mpz_clear((val)))
408#define value_read(val, str) (mpz_set_str((val), (str), 10))
409typedef void (*value_print_gmp_free_t)(void *, size_t);
410#define value_print(Dst, fmt, val) \
411 { \
412 char *str; \
413 value_print_gmp_free_t gmp_free; \
414 str = mpz_get_str(0, 10, (val)); \
415 fprintf((Dst), (fmt), str); \
416 mp_get_memory_functions(NULL, NULL, &gmp_free); \
417 (*gmp_free)(str, strlen(str) + 1); \
418 }
419#define value_swap(val1, val2) (mpz_swap(val1, val2))
420
421/* Boolean operators on 'Value' */
422#define value_eq(v1, v2) (mpz_cmp((v1), (v2)) == 0)
423#define value_ne(v1, v2) (mpz_cmp((v1), (v2)) != 0)
424#define value_gt(v1, v2) (mpz_cmp((v1), (v2)) > 0)
425#define value_ge(v1, v2) (mpz_cmp((v1), (v2)) >= 0)
426#define value_lt(v1, v2) (mpz_cmp((v1), (v2)) < 0)
427#define value_le(v1, v2) (mpz_cmp((v1), (v2)) <= 0)
428
429#define value_abs_eq(v1, v2) (mpz_cmpabs((v1), (v2)) == 0)
430#define value_abs_ne(v1, v2) (mpz_cmpabs((v1), (v2)) != 0)
431#define value_abs_gt(v1, v2) (mpz_cmpabs((v1), (v2)) > 0)
432#define value_abs_ge(v1, v2) (mpz_cmpabs((v1), (v2)) >= 0)
433#define value_abs_lt(v1, v2) (mpz_cmpabs((v1), (v2)) < 0)
434#define value_abs_le(v1, v2) (mpz_cmpabs((v1), (v2)) <= 0)
435
436/* Trian operators on 'Value' */
437#define value_sign(val) (mpz_sgn(val))
438#define value_cmp(v1, v2) (mpz_cmp((v1), (v2)))
439
440/* Binary operations on 'Value' */
441#define value_addto(ref, val1, val2) (mpz_add((ref), (val1), (val2)))
442#define value_add_int(ref, val, vint) (mpz_add_ui((ref), (val), (long)(vint)))
443#define value_addmul(ref, val1, val2) (mpz_addmul((ref), (val1), (val2)))
444#define value_increment(ref, val) (mpz_add_ui((ref), (val), 1))
445#define value_multiply(ref, val1, val2) (mpz_mul((ref), (val1), (val2)))
446#define value_subtract(ref, val1, val2) (mpz_sub((ref), (val1), (val2)))
447#define value_sub_int(ref, val, vint) (mpz_sub_ui((ref), (val), (long)(vint)))
448#define value_decrement(ref, val) (mpz_sub_ui((ref), (val), 1))
449#define value_division(ref, val1, val2) (mpz_tdiv_q((ref), (val1), (val2)))
450#define value_divexact(ref, val1, val2) (mpz_divexact((ref), (val1), (val2)))
451#define value_modulus(ref, val1, val2) (mpz_tdiv_r((ref), (val1), (val2)))
452#define value_pdivision(ref, val1, val2) (mpz_fdiv_q((ref), (val1), (val2)))
453#define value_pmodulus(ref, val1, val2) (mpz_fdiv_r((ref), (val1), (val2)))
454#define value_oppose(ref, val) (mpz_neg((ref), (val)))
455#define value_absolute(ref, val) (mpz_abs((ref), (val)))
456#define value_minimum(ref, val1, val2) \
457 (value_le((val1), (val2)) ? mpz_set((ref), (val1)) : mpz_set((ref), (val2)))
458#define value_maximum(ref, val1, val2) \
459 (value_ge((val1), (val2)) ? mpz_set((ref), (val1)) : mpz_set((ref), (val2)))
460#define value_gcd(ref, val1, val2) (mpz_gcd(ref, val1, val2))
461#define value_lcm(ref, val1, val2) (mpz_lcm(ref, val1, val2))
462#define value_orto(ref, val1, val2) (mpz_ior((ref), (val1), (val2)))
463#define value_andto(ref, val1, val2) (mpz_and((ref), (val1), (val2)))
464
465/* Conditional operations on 'Value' */
466#define value_pos_p(val) (mpz_sgn(val) > 0)
467#define value_neg_p(val) (mpz_sgn(val) < 0)
468#define value_posz_p(val) (mpz_sgn(val) >= 0)
469#define value_negz_p(val) (mpz_sgn(val) <= 0)
470#define value_zero_p(val) (mpz_sgn(val) == 0)
471#define value_notzero_p(val) (mpz_sgn(val) != 0)
472#define value_one_p(val) (mpz_cmp_si(val, 1) == 0)
473#define value_notone_p(val) (mpz_cmp_si(val, 1) != 0)
474#define value_mone_p(val) (mpz_cmp_si(val, -1) == 0)
475#define value_notmone_p(val) (mpz_cmp_si(val, -1) != 0)
476#define value_cmp_si(val, n) (mpz_cmp_si(val, n))
477
478/* end #if defined(GNUMP) */
479/* ************************************************************************* */
480#else
481/* 'Value' set to anything else: longlong|long|float|char *|int */
482
483/* Basic Macros */
484#define value_init(val) ((val) = 0)
485#define value_assign(v1, v2) ((v1) = (v2))
486#define value_set_si(val, i) ((val) = (Value)(i))
487#define value_set_double(val, d) ((val) = (Value)(d))
488#define value_clear(val) ((val) = 0)
489#define value_read(val, str) (sscanf((str), VALUE_FMT, &(val)))
490#define value_print(Dst, fmt, val) (fprintf((Dst), (fmt), (val)))
491#define value_swap(v1, v2) \
492 { \
493 Value tmp; \
494 tmp = v2; \
495 v2 = v1; \
496 v1 = tmp; \
497 }
498/* Cast to 'Value' */
499#define int_to_value(i) ((Value)(i))
500#define long_to_value(l) ((Value)(l))
501#define float_to_value(f) ((Value)(f))
502#define double_to_value(d) ((Value)(d))
503
504/* Boolean operators on 'Value' */
505#define value_eq(v1, v2) ((v1) == (v2))
506#define value_ne(v1, v2) ((v1) != (v2))
507#define value_gt(v1, v2) ((v1) > (v2))
508#define value_ge(v1, v2) ((v1) >= (v2))
509#define value_lt(v1, v2) ((v1) < (v2))
510#define value_le(v1, v2) ((v1) <= (v2))
511
512#define value_abs_eq(v1, v2) (value_abs(v1) == value_abs(v2))
513#define value_abs_ne(v1, v2) (value_abs(v1) != value_abs(v2))
514#define value_abs_gt(v1, v2) (value_abs(v1) > value_abs(v2))
515#define value_abs_ge(v1, v2) (value_abs(v1) >= value_abs(v2))
516#define value_abs_lt(v1, v2) (value_abs(v1) < value_abs(v2))
517#define value_abs_le(v1, v2) (value_abs(v1) <= value_abs(v2))
518
519/* Trian operators on 'Value' */
520#define value_sign(v) \
521 (value_eq(v, VALUE_ZERO) ? 0 : value_lt(v, VALUE_ZERO) ? -1 : 1)
522#define value_cmp(v1, v2) (value_eq(v1, v2) ? 0 : value_lt(v1, v2) ? -1 : 1)
523
524/* Binary operators on 'Value' */
525#define value_plus(v1, v2) ((v1) + (v2))
526#define value_div(v1, v2) ((v1) / (v2))
527#define value_mod(v1, v2) ((v1) % (v2))
528#define value_direct_multiply(v1, v2) ((v1) * (v2)) /* direct! */
529#define value_minus(v1, v2) ((v1) - (v2))
530#define value_pdiv(v1, v2) (DIVIDE((v1), (v2)))
531#define value_pmod(v1, v2) (MODULO((v1), (v2)))
532#define value_min(v1, v2) (value_le((v1), (v2)) ? (v1) : (v2))
533#define value_max(v1, v2) (value_ge((v1), (v2)) ? (v1) : (v2))
534#define value_or(v1, v2) ((v1) | (v2))
535#define value_and(v1, v2) ((v1) & (v2))
536#define value_lshift(v1, v2) ((v1) << (v2))
537#define value_rshift(v1, v2) ((v1) >> (v2))
538
539/* Binary operations on 'Value' */
540#define value_addto(ref, val1, val2) ((ref) = (val1) + (val2))
541#define value_add_int(ref, val, vint) ((ref) = (val) + (Value)(vint))
542#define value_addmul(ref, val1, val2) ((ref) += (val1) * (val2))
543#define value_increment(ref, val) ((ref) = (val) + VALUE_ONE)
544#define value_direct_product(ref, val1, val2) \
545 ((ref) = (val1) * (val2)) /* direct! */
546#define value_multiply(ref, val1, val2) ((ref) = value_mult((val1), (val2)))
547#define value_subtract(ref, val1, val2) ((ref) = (val1) - (val2))
548#define value_sub_int(ref, val, vint) ((ref) = (val) - (Value)(vint))
549#define value_decrement(ref, val) ((ref) = (val) - VALUE_ONE)
550#define value_division(ref, val1, val2) ((ref) = (val1) / (val2))
551#define value_divexact(ref, val1, val2) ((ref) = (val1) / (val2))
552#define value_modulus(ref, val1, val2) ((ref) = (val1) % (val2))
553#define value_pdivision(ref, val1, val2) ((ref) = value_pdiv((val1), (val2)))
554#define value_pmodulus(ref, val1, val2) ((ref) = value_pmod((val1), (val2)))
555#define value_oppose(ref, val) ((ref) = value_uminus((val)))
556#define value_absolute(ref, val) ((ref) = value_abs((val)))
557#define value_minimum(ref, val1, val2) ((ref) = value_min((val1), (val2)))
558#define value_maximum(ref, val1, val2) ((ref) = value_max((val1), (val2)))
559#define value_gcd(ref, val1, val2) Gcd((val1), (val2), &(ref))
560#define value_lcm(ref, val1, val2) Lcm3((val1), (val2), &(ref))
561#define value_orto(ref, val1, val2) ((ref) = (val1) | (val2))
562#define value_andto(ref, val1, val2) ((ref) = (val1) & (val2))
563
564/* Unary operators on 'Value' */
565#define value_uminus(val) (-(val))
566#define value_not(val) (~(val))
567#define value_abs(val) \
568 (value_posz_p(val) \
569 ? (val) \
570 : (value_ne((val), VALUE_NAN) ? value_uminus(val) \
571 : (THROW(overflow_error), VALUE_NAN)))
572
573/* Conditional operations on 'Value' */
574#define value_pos_p(val) value_gt(val, VALUE_ZERO)
575#define value_neg_p(val) value_lt(val, VALUE_ZERO)
576#define value_posz_p(val) value_ge(val, VALUE_ZERO)
577#define value_negz_p(val) value_le(val, VALUE_ZERO)
578#define value_zero_p(val) value_eq(val, VALUE_ZERO)
579#define value_notzero_p(val) value_ne(val, VALUE_ZERO)
580#define value_one_p(val) value_eq(val, VALUE_ONE)
581#define value_notone_p(val) value_ne(val, VALUE_ONE)
582#define value_mone_p(val) value_eq(val, VALUE_MONE)
583#define value_notmone_p(val) value_ne(val, VALUE_MONE)
584#define value_cmp_si(val, n) (val - (n))
585#define value_min_p(val) value_eq(val, VALUE_MIN)
586#define value_max_p(val) value_eq(val, VALUE_MAX)
587#define value_notmin_p(val) value_ne(val, VALUE_MIN)
588#define value_notmax_p(val) value_ne(val, VALUE_MAX)
589
590#endif /* 'Value' set to |longlong|long|float|char *|int */
591
592/* *********************** PROTECTED MULTIPLICATION ********************** */
593#include "arithmetic_errors.h"
594
595/* (|v| < MAX / |w|) => v*w is okay
596 * I could check ((v*w)/w)==v but a tmp would be useful
597 */
598#define value_protected_hard_idiv_multiply(v, w, throw) \
599 ((value_zero_p(w) || value_zero_p(v)) ? VALUE_ZERO \
600 : value_lt(value_abs(v), value_div(VALUE_MAX, value_abs(w))) \
601 ? value_direct_multiply(v, w) \
602 : (throw, VALUE_NAN))
603
604/* is a software idiv is assumed, quick check performed first
605 */
606#if defined(LINEAR_VALUE_ASSUME_SOFTWARE_IDIV)
607#define value_protected_multiply(v, w, throw) \
608 ((value_le(v, VALUE_SQRT_MAX) && value_le(w, VALUE_SQRT_MAX) && \
609 value_ge(v, VALUE_SQRT_MIN) && value_ge(w, VALUE_SQRT_MIN)) \
610 ? value_direct_multiply(v, w) \
611 : value_protected_hard_idiv_multiply(v, w, throw))
612#else
613#define value_protected_multiply(v, w, throw) \
614 value_protected_hard_idiv_multiply(v, w, throw)
615#endif
616
617/* protected versions
618 */
619#define value_protected_mult(v, w) \
620 value_protected_multiply(v, w, THROW(overflow_error))
621#define value_protected_product(v, w) v = value_protected_mult(v, w)
622
623/* whether the default is protected or not
624 * this define makes no sense any more... well, doesn't matter. FC.
625 */
626#if defined(LINEAR_VALUE_PROTECT_MULTIPLY)
627#define value_mult(v, w) value_protected_mult(v, w)
628#define value_product(v, w) value_protected_product(v, w)
629#else
630
631/* I do enforce the protection whatever requested:-)
632 * prints out a message and throws the exception, hoping
633 * that some valid CATCH waits for it upwards.
634 */
635#define value_mult(v, w) \
636 value_protected_multiply(v, w, \
637 (fprintf(stderr, "[value_mult] value overflow!\n"), \
638 THROW(overflow_error)))
639#define value_product(v, w) v = value_mult(v, w)
640
641/* was:
642 * #define value_mult(v,w) value_direct_multiply(v,w)
643 * #define value_product(v,w) value_direct_product(v,w)
644 * could be: protected versions...
645 */
646#endif
647
648/******************************************************* STATIC VALUE DEBUG */
649
650/* LINEAR_VALUE_IS_CHARS is used for type checking.
651 * some operations are not allowed on (char*), thus
652 * they are switched to some other operation here...
653 */
654#if defined(LINEAR_VALUE_IS_CHARS)
655#undef value_init
656#define value_init(val) ((val).s = NULL)
657#undef value_clear
658#define value_clear(val) (value_init(val))
659#define value_fake_binary(v1, v2) ((Value)((v1).i + (v2).i))
660#define value_fake_ternary(v0, v1, v2) ((Value)((v0).i += (v1).i + (v2).i))
661#define value_bool_binary(v1, v2) ((int)((v1).i + (v2).i))
662#undef float_to_value
663#define float_to_value(f) ((Value)f)
664#undef double_to_value
665#define double_to_value(f) ((Value)f)
666#undef value_uminus
667#define value_uminus(v) (v)
668#undef value_mult
669#define value_mult(v1, v2) value_fake_binary(v1, v2)
670#undef value_mod
671#define value_mod(v1, v2) value_fake_binary(v1, v2)
672#undef value_ge
673#define value_ge(v1, v2) value_bool_binary(v1, v2)
674#undef value_gt
675#define value_gt(v1, v2) value_bool_binary(v1, v2)
676#undef value_le
677#define value_le(v1, v2) value_bool_binary(v1, v2)
678#undef value_lt
679#define value_lt(v1, v2) value_bool_binary(v1, v2)
680#undef value_ne
681#define value_ne(v1, v2) value_bool_binary(v1, v2)
682#undef value_eq
683#define value_eq(v1, v2) value_bool_binary(v1, v2)
684#undef value_plus
685#define value_plus(v1, v2) value_fake_binary(v1, v2)
686#undef value_minus
687#define value_minus(v1, v2) value_fake_binary(v1, v2)
688#undef value_pdiv
689#define value_pdiv(v1, v2) value_fake_binary(v1, v2)
690#undef value_div
691#define value_div(v1, v2) value_fake_binary(v1, v2)
692#undef value_mod
693#define value_mod(v1, v2) value_fake_binary(v1, v2)
694#undef value_addto
695#define value_addto(v1, v2) value_assign(v1, value_plus(v1, v2))
696#undef value_subtract
697#define value_subtract(v1, v2) value_addto(v1, v2)
698#undef value_product
699#define value_product(v1, v2) value_addto(v1, v2)
700#undef value_modulus
701#define value_modulus(v1, v2) value_addto(v1, v2)
702#undef value_division
703#define value_division(ref, val1, val2) (value_fake_ternary(ref, val1, val2))
704#undef value_divexact
705#define value_divexact(ref, v1, v2) (value_fake_ternary(ref, val1, val2))
706#undef value_increment
707#define value_increment(v) value_addto(v, VALUE_ONE)
708#undef value_decrement
709#define value_decrement(v) value_addto(v, VALUE_MONE)
710#undef value_orto
711#define value_orto(ref, val) value_addto(v1, v2)
712#undef value_andto
713#define value_andto(ref, val) value_addto(v1, v2)
714#undef value_or
715#define value_or(v1, v2) value_fake_binary(v1, v2)
716#undef value_and
717#define value_and(v1, v2) value_fake_binary(v1, v2)
718#undef value_lshift
719#define value_lshift(v1, v2) value_fake_binary(v1, v2)
720#undef value_rshift
721#define value_rshift(v1, v2) value_fake_binary(v1, v2)
722#endif
723
724/* for backward compatibility */
725#define value_substract(ref, val1, val2) (value_subtract((ref), (val1), (val2)))
726
727/* valeur absolue
728 */
729#ifndef ABS
730#define ABS(x) (((x) >= 0) ? (x) : -(x))
731#endif
732
733/* minimum et maximum
734 * if they are defined somewhere else, they are very likely
735 * to be defined the same way. Thus the previous def is not overwritten.
736 */
737#ifndef MIN
738#define MIN(x, y) (((x) >= (y)) ? (y) : (x))
739#endif
740#ifndef MAX
741#define MAX(x, y) (((x) >= (y)) ? (x) : (y))
742#endif
743
744/* signe d'un entier: -1, 0 ou 1 */
745#define SIGN(x) (((x) > 0) ? 1 : ((x) == 0 ? 0 : -1))
746
747/* division avec reste toujours positif
748 * basee sur les equations:
749 * a/(-b) = - (a/b)
750 * (-a)/b = - ((a+b-1)/b)
751 * ou a et b sont des entiers positifs
752 */
753#define DIVIDE(x, y) \
754 ((y) > 0 ? POSITIVE_DIVIDE(x, y) : -POSITIVE_DIVIDE((x), (-(y))))
755
756/* division avec reste toujours positif quand y est positif: assert(y>=0) */
757#define POSITIVE_DIVIDE(x, y) ((x) > 0 ? (x) / (y) : -(-(x) + (y) - 1) / (y))
758
759/* modulo a resultat toujours positif */
760#define MODULO(x, y) ((y) > 0 ? POSITIVE_MODULO(x, y) : POSITIVE_MODULO(-x, -y))
761
762/* modulo par rapport a un nombre positif: assert(y>=0)
763 *
764 * Ce n'est pas la macro la plus efficace que j'aie jamais ecrite: il faut
765 * faire, dans le pire des cas, deux appels a la routine .rem, qui n'est
766 * surement pas plus cablee que la division ou la multiplication
767 */
768#define POSITIVE_MODULO(x, y) \
769 ((x) > 0 ? (x) % (y) : ((x) % (y) == 0 ? 0 : ((y) - (-(x)) % (y))))
770
771/* errors.c */
772extern unsigned int overflow_error;
773extern unsigned int simplex_arithmetic_error;
774extern unsigned int user_exception_error;
775extern unsigned int parser_exception_error;
776extern unsigned int any_exception_error;
777extern unsigned int the_last_just_thrown_exception;
778extern void dump_exception_stack_to_file(FILE * /*f*/);
779extern void dump_exception_stack(void);
780extern jmp_buf *push_exception_on_stack(int /*what*/, const char * /*function*/,
781 const char * /*file*/, int /*line*/);
782extern void pop_exception_from_stack(int /*what*/, const char * /*function*/,
783 const char * /*file*/, int /*line*/);
784extern void throw_exception(int /*what*/, const char * /*function*/,
785 const char * /*file*/, int /*line*/);
786extern void free_exception_stack(void);
787
788#endif /* arithmetique_header_included */
unsigned int user_exception_error
Definition: errors.c:98
unsigned int parser_exception_error
Definition: errors.c:99
unsigned int simplex_arithmetic_error
Definition: errors.c:97
unsigned int any_exception_error
Definition: errors.c:103
void dump_exception_stack(void)
Definition: errors.c:257
void pop_exception_from_stack(int, const char *, const char *, int)
Definition: errors.c:308
jmp_buf * push_exception_on_stack(int, const char *, const char *, int)
Definition: errors.c:270
int Value
Definition: arithmetique.h:294
void throw_exception(int, const char *, const char *, int)
Definition: errors.c:352
void dump_exception_stack_to_file(FILE *)
Definition: errors.c:240
unsigned int the_last_just_thrown_exception
Definition: errors.c:141
void free_exception_stack(void)
Definition: errors.c:207
unsigned int overflow_error
Definition: errors.c:96
char s[128]
Definition: polytest.c:8