Files GPLv3 headers removed
[polylib.git] / source / arith / arithmetique.h
blob123f2f9a84691eae00efcdb474ccd9d37d5810ad
1 /* header file built by cproto */
2 #ifndef arithmetique_header_included
3 #define arithmetique_header_included
5 /** package arithmetique
7 * $Id: arithmetique.h,v 1.24 2007/02/22 09:16:57 skimo Exp $
9 * Francois Irigoin, mai 1989
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)
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.
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...
28 * Fabien COELHO
31 #include <stdio.h>
32 #include <limits.h> /* Included for getting constants: INT_MAX, etc.. */
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)
40 extern "C" {
41 #endif
42 void mp_get_memory_functions(
43 void *(**alloc_func_ptr) (size_t),
44 void *(**realloc_func_ptr) (void *, size_t, size_t),
45 void (**free_func_ptr) (void *, size_t));
46 #if defined(__cplusplus)
48 #endif
49 #endif
50 #endif
52 #ifdef CLN
53 #include <sstream>
54 #define WANT_OBFUSCATING_OPERATORS
55 #include <cln/cln.h>
56 #endif
58 /*
59 # #### # # #### # #### # # ####
60 # # # ## # # # # # # ## # # #
61 # # # # # # # # # # # # # #
62 # # # # # # # ### # # # # # # # ###
63 # # # # ## # # # # # # ## # #
64 ###### #### # # #### ###### #### # # ####
68 /*
69 * Constants like LONG_LONG_MAX are not defined with ansi options, so they are
70 * defined here.
71 */
73 #ifndef LONG_LONG_MAX
75 /* would fix on solaris:
76 * #define LONG_LONG_MAX LLONG_MAX
77 * #define LONG_LONG_MIN LLONG_MIN
80 #ifndef __LONG_LONG_MAX__
81 #define __LONG_LONG_MAX__ 9223372036854775807LL
82 #endif
83 #undef LONG_LONG_MAX
84 #define LONG_LONG_MAX __LONG_LONG_MAX__
85 #undef LONG_LONG_MIN
86 #define LONG_LONG_MIN (-LONG_LONG_MAX-1)
87 #undef ULONG_LONG_MAX
88 #define ULONG_LONG_MAX (LONG_LONG_MAX * 2ULL + 1)
89 #endif
91 #if defined(LINEAR_VALUE_IS_LONGLONG)
93 #define LINEAR_VALUE_STRING "long long int"
94 typedef 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)
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
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)
117 #define VALUE_TO_LONG(val) \
118 ((long)((val)>(Value)LONG_MIN&&(val)<=(Value)LONG_MAX)?\
119 (val):(THROW(overflow_error), LONG_MIN))
121 #define VALUE_TO_INT(val) \
122 ((int)((val)>(Value)INT_MIN&&(val)<=(Value)INT_MAX)?\
123 (val):(THROW(overflow_error), INT_MIN))
125 #define VALUE_TO_DOUBLE(val) ((double)(val))
127 /* #define VALUE_TO_FLOAT(val) ((float)(val)): Doesn't seem to work with gcc */
128 #define VALUE_TO_FLOAT(val) ((float)((int)(val)))
130 /* end LINEAR_VALUE_IS_LONGLONG */
134 # #### # # ####
135 # # # ## # # #
136 # # # # # # #
137 # # # # # # # ###
138 # # # # ## # #
139 ###### #### # # ####
143 #elif defined(LINEAR_VALUE_IS_LONG)
145 #define LINEAR_VALUE_STRING "long int"
146 typedef long Value;
147 #define VALUE_FMT "%ld"
148 #define VALUE_CONST(val) (val##L)
149 #define VALUE_NAN LONG_MIN
150 #define VALUE_MIN (LONG_MIN+1L)
151 #define VALUE_MAX LONG_MAX
152 #define VALUE_SQRT_MIN int_to_value(INT_MIN)
153 #define VALUE_SQRT_MAX int_to_value(INT_MAX)
154 #define VALUE_ZERO 0L
155 #define VALUE_ONE 1L
156 #define VALUE_MONE -1L
157 #define VALUE_TO_LONG(val) (val)
158 #define VALUE_TO_INT(val) ((int)(val))
159 #define VALUE_TO_FLOAT(val) ((float)(val))
160 #define VALUE_TO_DOUBLE(val) ((double)(val))
162 /* end LINEAR_VALUE_IS_LONG */
165 ###### # #### ## #####
166 # # # # # # #
167 ##### # # # # # #
168 # # # # ###### #
169 # # # # # # #
170 # ###### #### # # #
175 #elif defined(LINEAR_VALUE_IS_FLOAT)
177 #define LINEAR_VALUE_STRING "float"
178 typedef float Value;
179 #define VALUE_FMT "%f"
180 #define VALUE_CONST(val) (val)
181 #define VALUE_MIN FLOAT_MIN
182 #define VALUE_MAX FLOAT_MAX
183 #define VALUE_ZERO 0.0
184 #define VALUE_ONE 1.0
185 #define VALUE_MONE -1.0
186 #define VALUE_TO_LONG(val) ((long)(val))
187 #define VALUE_TO_INT(val) ((int)(val))
188 #define VALUE_TO_FLOAT(val) ((float)(val))
189 #define VALUE_TO_DOUBLE(val) ((double)(val))
193 /* end LINEAR_VALUE_IS_FLOAT */
196 #### # # ## ##### # #
197 # # # # # # # # # #
198 # ###### # # # # #######
199 # # # ###### ##### # #
200 # # # # # # # # # #
201 #### # # # # # #
205 /* Char version is used to detect invalid assignments */
207 #elif defined(LINEAR_VALUE_IS_CHARS)
209 #define LINEAR_VALUE_STRING "char"
210 typedef union { char *s; long l; int i; float f; double d;} Value;
211 #define VALUE_FMT "%s"
212 #define VALUE_CONST(val) ((Value)(val))
213 #define VALUE_NAN ((Value)(long)0xdadeebee)
214 #define VALUE_MIN ((Value)(long)0xdeadbeef)
215 #define VALUE_MAX ((Value)(long)0xfeedabee)
216 #define VALUE_ZERO ((Value)0)
217 #define VALUE_ONE ((Value)1)
218 #define VALUE_MONE ((Value)-1)
219 #define VALUE_TO_LONG(val) (val.l)
220 #define VALUE_TO_INT(val) (val.i)
221 #define VALUE_TO_FLOAT(val) (val.f)
222 #define VALUE_TO_DOUBLE(val) (val.d)
224 /* end LINEAR_VALUE_IS_CHARS */
227 # # # #####
228 # ## # #
229 # # # # #
230 # # # # #
231 # # ## #
232 # # # #
236 #elif defined(LINEAR_VALUE_IS_INT)
238 #define LINEAR_VALUE_STRING "int"
239 typedef int Value;
240 #define VALUE_FMT "%d"
241 #define VALUE_CONST(val) (val)
242 #define VALUE_NAN INT_MIN
243 #define VALUE_MIN (INT_MIN+1)
244 #define VALUE_MAX INT_MAX
245 #define VALUE_ZERO 0
246 #define VALUE_ONE 1
247 #define VALUE_MONE -1
248 #define VALUE_TO_LONG(val) ((long)(val))
249 #define VALUE_TO_INT(val) ((int)(val))
250 #define VALUE_TO_FLOAT(val) ((float)(val))
251 #define VALUE_TO_DOUBLE(val) ((double)(val))
253 /* end LINEAR_VALUE_IS_INT */
255 #elif defined(GNUMP)
257 #define LINEAR_VALUE_STRING "gmp"
258 typedef mpz_t Value;
259 #define VALUE_FMT "%s"
261 /* don't use these, use value_set_si instead ! */
262 #undef VALUE_ZERO
263 #undef VALUE_ONE
264 #undef VALUE_MONE
265 #define VALUE_TO_LONG(val) (mpz_get_si(val))
266 #define VALUE_TO_INT(val) ((int)mpz_get_si(val))
267 #define VALUE_TO_FLOAT(val) ((float)((int)mpz_get_si(val)))
268 #define VALUE_TO_DOUBLE(val) (mpz_get_d(val))
270 #elif defined(CLN)
272 #define LINEAR_VALUE_STRING "cln"
273 typedef cln::cl_I Value;
274 #define VALUE_FMT "%s"
276 #define VALUE_TO_INT(val) (cln::cl_I_to_int(val))
277 #define VALUE_TO_DOUBLE(val) (cln::double_approx(val))
279 #endif
281 /* ***************** MACROS FOR MANIPULATING VALUES ******************** */
283 #if defined(CLN)
285 #define value_init(val) ((val).word = ((cln::cl_uint)cl_FN_tag) << cl_tag_shift)
286 #define value_assign(v1,v2) ((v1) = (v2))
287 #define value_set_si(val,i) ((val) = (i))
288 #define value_set_double(val,d) ((val) = cln::truncate1(cln::cl_R(d)))
289 #define value_clear(val) ((val) = 0)
290 #define value_read(val,str) ((val) = (str))
291 #define value_print(Dst,fmt,val) {std::ostringstream strm; strm << val; \
292 fprintf((Dst),(fmt),strm.str().c_str()); \
294 #define value_swap(v1,v2) {Value tmp; tmp = v2; \
295 v2 = v1; v1 = tmp; \
298 /* Boolean operators on 'Value' */
300 #define value_eq(v1,v2) ((v1)==(v2))
301 #define value_ne(v1,v2) ((v1)!=(v2))
302 #define value_gt(v1,v2) ((v1)>(v2))
303 #define value_ge(v1,v2) ((v1)>=(v2))
304 #define value_lt(v1,v2) ((v1)<(v2))
305 #define value_le(v1,v2) ((v1)<=(v2))
307 #define value_abs_eq(v1,v2) (cln::abs(v1)==cln::abs(v2))
308 #define value_abs_ne(v1,v2) (cln::abs(v1)!=cln::abs(v2))
309 #define value_abs_gt(v1,v2) (cln::abs(v1)>cln::abs(v2))
310 #define value_abs_ge(v1,v2) (cln::abs(v1)>=cln::abs(v2))
311 #define value_abs_lt(v1,v2) (cln::abs(v1)<cln::abs(v2))
312 #define value_abs_le(v1,v2) (cln::abs(v1)<=cln::abs(v2))
314 #define value_sign(val) (cln::signum(val))
315 #define value_cmp(v1,v2) (cln::compare((v1),(v2)))
317 #define value_addto(ref,val1,val2) ((ref) = (val1)+(val2))
318 #define value_add_int(ref,val,vint) ((ref) = (val)+(vint))
319 #define value_addmul(ref, val1, val2) ((ref) += (val1)*(val2))
320 #define value_increment(ref,val) ((ref) = (val)+1)
321 #define value_multiply(ref,val1,val2) ((ref) = (val1)*(val2))
322 #define value_subtract(ref,val1,val2) ((ref) = (val1)-(val2))
323 #define value_sub_int(ref,val1,val2) ((ref) = (val1)-(val2))
324 #define value_decrement(ref,val) ((ref) = (val)-1)
325 #define value_division(ref,val1,val2) ((ref) = cln::truncate1(val1,val2))
326 #define value_divexact(ref,val1,val2) ((ref) = cln::exquo(val1,val2))
327 #define value_modulus(ref,val1,val2) ((ref) = cln::truncate2(val1,val2).remainder)
328 #define value_pdivision(ref,val1,val2) ((ref) = cln::floor1(val1,val2))
329 #define value_pmodulus(ref,val1,val2) ((ref) = cln::floor2(val1,val2).remainder)
330 #define value_oppose(ref,val) ((ref) = -(val))
331 #define value_absolute(ref,val) ((ref) = cln::abs(val))
332 #define value_minimum(ref,val1,val2) ((ref) = cln::min((val1),(val2)))
333 #define value_maximum(ref,val1,val2) ((ref) = cln::max((val1),(val2)))
334 #define value_gcd(ref,val1,val2) ((ref) = cln::gcd((val1),(val2)))
335 #define value_lcm(ref,val1,val2) ((ref) = cln::lcm((val1),(val2)))
336 #define value_orto(ref,val1,val2) ((ref) = (val1)|(val2))
337 #define value_andto(ref,val1,val2) ((ref) = (val1)&(val2))
339 /* Conditional operations on 'Value' */
341 #define value_pos_p(val) ((val) > 0)
342 #define value_neg_p(val) ((val) < 0)
343 #define value_posz_p(val) ((val) >= 0)
344 #define value_negz_p(val) ((val) <= 0)
345 #define value_zero_p(val) ((val) == 0)
346 #define value_notzero_p(val) ((val) != 0)
347 #define value_one_p(val) ((val) == 1)
348 #define value_notone_p(val) ((val) != 1)
349 #define value_mone_p(val) ((val) == -1)
350 #define value_notmone_p(val) ((val) != -1)
351 #define value_cmp_si(val, n) (cln::compare(val,n))
353 #elif defined(GNUMP)
355 /* Basic macros */
357 #define value_init(val) (mpz_init((val)))
358 #define value_assign(v1,v2) (mpz_set((v1),(v2)))
359 #define value_set_si(val,i) (mpz_set_si((val),(i)))
360 #define value_set_double(val,d)(mpz_set_d((val),(d)))
361 #define value_clear(val) (mpz_clear((val)))
362 #define value_read(val,str) (mpz_set_str((val),(str),10))
363 typedef void (*value_print_gmp_free_t)(void *, size_t);
364 #define value_print(Dst,fmt,val) {char *str; \
365 value_print_gmp_free_t gmp_free; \
366 str = mpz_get_str(0,10,(val)); \
367 fprintf((Dst),(fmt),str); \
368 mp_get_memory_functions(NULL, NULL, &gmp_free); \
369 (*gmp_free) (str, strlen(str)+1); \
371 #define value_swap(val1,val2) (mpz_swap(val1, val2))
373 /* Boolean operators on 'Value' */
375 #define value_eq(v1,v2) (mpz_cmp((v1),(v2)) == 0)
376 #define value_ne(v1,v2) (mpz_cmp((v1),(v2)) != 0)
377 #define value_gt(v1,v2) (mpz_cmp((v1),(v2)) > 0)
378 #define value_ge(v1,v2) (mpz_cmp((v1),(v2)) >= 0)
379 #define value_lt(v1,v2) (mpz_cmp((v1),(v2)) < 0)
380 #define value_le(v1,v2) (mpz_cmp((v1),(v2)) <= 0)
382 #define value_abs_eq(v1,v2) (mpz_cmpabs((v1),(v2)) == 0)
383 #define value_abs_ne(v1,v2) (mpz_cmpabs((v1),(v2)) != 0)
384 #define value_abs_gt(v1,v2) (mpz_cmpabs((v1),(v2)) > 0)
385 #define value_abs_ge(v1,v2) (mpz_cmpabs((v1),(v2)) >= 0)
386 #define value_abs_lt(v1,v2) (mpz_cmpabs((v1),(v2)) < 0)
387 #define value_abs_le(v1,v2) (mpz_cmpabs((v1),(v2)) <= 0)
389 /* Trian operators on 'Value' */
391 #define value_sign(val) (mpz_sgn(val))
392 #define value_cmp(v1,v2) (mpz_cmp((v1),(v2)))
394 /* Binary operations on 'Value' */
396 #define value_addto(ref,val1,val2) (mpz_add((ref),(val1),(val2)))
397 #define value_add_int(ref,val,vint) (mpz_add_ui((ref),(val),(long)(vint)))
398 #define value_addmul(ref, val1, val2) (mpz_addmul((ref), (val1), (val2)))
399 #define value_increment(ref,val) (mpz_add_ui((ref),(val),1))
400 #define value_multiply(ref,val1,val2) (mpz_mul((ref),(val1),(val2)))
401 #define value_subtract(ref,val1,val2) (mpz_sub((ref),(val1),(val2)))
402 #define value_sub_int(ref,val,vint) (mpz_sub_ui((ref),(val),(long)(vint)))
403 #define value_decrement(ref,val) (mpz_sub_ui((ref),(val),1))
404 #define value_division(ref,val1,val2) (mpz_tdiv_q((ref),(val1),(val2)))
405 #define value_divexact(ref,val1,val2) (mpz_divexact((ref),(val1),(val2)))
406 #define value_modulus(ref,val1,val2) (mpz_tdiv_r((ref),(val1),(val2)))
407 #define value_pdivision(ref,val1,val2) (mpz_fdiv_q((ref),(val1),(val2)))
408 #define value_pmodulus(ref,val1,val2) (mpz_fdiv_r((ref),(val1),(val2)))
409 #define value_oppose(ref,val) (mpz_neg((ref),(val)))
410 #define value_absolute(ref,val) (mpz_abs((ref),(val)))
411 #define value_minimum(ref,val1,val2) (value_le((val1),(val2)) ? \
412 mpz_set((ref),(val1)) : \
413 mpz_set((ref),(val2)))
414 #define value_maximum(ref,val1,val2) (value_ge((val1),(val2)) ? \
415 mpz_set((ref),(val1)) : \
416 mpz_set((ref),(val2)))
417 #define value_gcd(ref,val1,val2) (mpz_gcd(ref,val1,val2))
418 #define value_lcm(ref,val1,val2) (mpz_lcm(ref,val1,val2))
419 #define value_orto(ref,val1,val2) (mpz_ior((ref),(val1),(val2)))
420 #define value_andto(ref,val1,val2) (mpz_and((ref),(val1),(val2)))
422 /* Conditional operations on 'Value' */
424 #define value_pos_p(val) (mpz_sgn(val) > 0)
425 #define value_neg_p(val) (mpz_sgn(val) < 0)
426 #define value_posz_p(val) (mpz_sgn(val) >= 0)
427 #define value_negz_p(val) (mpz_sgn(val) <= 0)
428 #define value_zero_p(val) (mpz_sgn(val) == 0)
429 #define value_notzero_p(val) (mpz_sgn(val) != 0)
430 #define value_one_p(val) (mpz_cmp_si(val,1) == 0)
431 #define value_notone_p(val) (mpz_cmp_si(val,1) != 0)
432 #define value_mone_p(val) (mpz_cmp_si(val,-1) ==0)
433 #define value_notmone_p(val) (mpz_cmp_si(val,-1) !=0)
434 #define value_cmp_si(val, n) (mpz_cmp_si(val,n))
436 /* ************************************************************************* */
438 #else /* 'Value' set to longlong|long|float|char *|int */
439 /* Basic Macros */
441 #define value_init(val) ((val) = 0)
442 #define value_assign(v1,v2) ((v1) = (v2))
443 #define value_set_si(val,i) ((val) = (Value)(i))
444 #define value_set_double(val,d) ((val) = (Value)(d))
445 #define value_clear(val) ((val) = 0)
446 #define value_read(val,str) (sscanf((str),VALUE_FMT,&(val)))
447 #define value_print(Dst,fmt,val) (fprintf((Dst),(fmt),(val)))
448 #define value_swap(v1,v2) {Value tmp; tmp = v2; \
449 v2 = v1; v1 = tmp; \
451 /* Cast to 'Value' */
453 #define int_to_value(i) ((Value)(i))
454 #define long_to_value(l) ((Value)(l))
455 #define float_to_value(f) ((Value)(f))
456 #define double_to_value(d) ((Value)(d))
458 /* Boolean operators on 'Value' */
460 #define value_eq(v1,v2) ((v1)==(v2))
461 #define value_ne(v1,v2) ((v1)!=(v2))
462 #define value_gt(v1,v2) ((v1)>(v2))
463 #define value_ge(v1,v2) ((v1)>=(v2))
464 #define value_lt(v1,v2) ((v1)<(v2))
465 #define value_le(v1,v2) ((v1)<=(v2))
467 #define value_abs_eq(v1,v2) (value_abs(v1)==value_abs(v2))
468 #define value_abs_ne(v1,v2) (value_abs(v1)!=value_abs(v2))
469 #define value_abs_gt(v1,v2) (value_abs(v1)>value_abs(v2))
470 #define value_abs_ge(v1,v2) (value_abs(v1)>=value_abs(v2))
471 #define value_abs_lt(v1,v2) (value_abs(v1)<value_abs(v2))
472 #define value_abs_le(v1,v2) (value_abs(v1)<=value_abs(v2))
474 /* Trian operators on 'Value' */
476 #define value_sign(v) (value_eq(v,VALUE_ZERO)?0:value_lt(v,VALUE_ZERO)?-1:1)
477 #define value_cmp(v1,v2) (value_eq(v1,v2)?0:value_lt(v1,v2)?-1:1)
479 /* Binary operators on 'Value' */
481 #define value_plus(v1,v2) ((v1)+(v2))
482 #define value_div(v1,v2) ((v1)/(v2))
483 #define value_mod(v1,v2) ((v1)%(v2))
484 #define value_direct_multiply(v1,v2) ((v1)*(v2)) /* direct! */
485 #define value_minus(v1,v2) ((v1)-(v2))
486 #define value_pdiv(v1,v2) (DIVIDE((v1),(v2)))
487 #define value_pmod(v1,v2) (MODULO((v1),(v2)))
488 #define value_min(v1,v2) (value_le((v1),(v2))? (v1): (v2))
489 #define value_max(v1,v2) (value_ge((v1),(v2))? (v1): (v2))
490 #define value_or(v1,v2) ((v1)|(v2))
491 #define value_and(v1,v2) ((v1)&(v2))
492 #define value_lshift(v1,v2) ((v1)<<(v2))
493 #define value_rshift(v1,v2) ((v1)>>(v2))
495 /* Binary operations on 'Value' */
497 #define value_addto(ref,val1,val2) ((ref) = (val1)+(val2))
498 #define value_add_int(ref,val,vint) ((ref) = (val)+(Value)(vint))
499 #define value_addmul(ref, val1, val2) ((ref) += (val1)*(val2))
500 #define value_increment(ref,val) ((ref) = (val)+VALUE_ONE)
501 #define value_direct_product(ref,val1,val2) ((ref) = (val1)*(val2)) /* direct! */
502 #define value_multiply(ref,val1,val2) ((ref) = value_mult((val1),(val2)))
503 #define value_subtract(ref,val1,val2) ((ref) = (val1)-(val2))
504 #define value_sub_int(ref,val,vint) ((ref) = (val)-(Value)(vint))
505 #define value_decrement(ref,val) ((ref) = (val)-VALUE_ONE)
506 #define value_division(ref,val1,val2) ((ref) = (val1)/(val2))
507 #define value_divexact(ref,val1,val2) ((ref) = (val1)/(val2))
508 #define value_modulus(ref,val1,val2) ((ref) = (val1)%(val2))
509 #define value_pdivision(ref,val1,val2) ((ref) = value_pdiv((val1),(val2)))
510 #define value_pmodulus(ref,val1,val2) ((ref) = value_pmod((val1),(val2)))
511 #define value_oppose(ref,val) ((ref) = value_uminus((val)))
512 #define value_absolute(ref,val) ((ref) = value_abs((val)))
513 #define value_minimum(ref,val1,val2) ((ref) = value_min((val1),(val2)))
514 #define value_maximum(ref,val1,val2) ((ref) = value_max((val1),(val2)))
515 #define value_gcd(ref,val1,val2) Gcd((val1),(val2),&(ref))
516 #define value_lcm(ref,val1,val2) Lcm3((val1),(val2),&(ref))
517 #define value_orto(ref,val1,val2) ((ref) = (val1)|(val2))
518 #define value_andto(ref,val1,val2) ((ref) = (val1)&(val2))
520 /* Unary operators on 'Value' */
522 #define value_uminus(val) (-(val))
523 #define value_not(val) (~(val))
524 #define value_abs(val) (value_posz_p(val)? \
525 (val) : \
526 (value_ne((val), VALUE_NAN) ? \
527 value_uminus(val) : \
528 (THROW (overflow_error), VALUE_NAN )))
530 /* Conditional operations on 'Value' */
532 #define value_pos_p(val) value_gt(val,VALUE_ZERO)
533 #define value_neg_p(val) value_lt(val,VALUE_ZERO)
534 #define value_posz_p(val) value_ge(val,VALUE_ZERO)
535 #define value_negz_p(val) value_le(val,VALUE_ZERO)
536 #define value_zero_p(val) value_eq(val,VALUE_ZERO)
537 #define value_notzero_p(val) value_ne(val,VALUE_ZERO)
538 #define value_one_p(val) value_eq(val,VALUE_ONE)
539 #define value_notone_p(val) value_ne(val,VALUE_ONE)
540 #define value_mone_p(val) value_eq(val,VALUE_MONE)
541 #define value_notmone_p(val) value_ne(val,VALUE_MONE)
542 #define value_cmp_si(val, n) (val - (n))
543 #define value_min_p(val) value_eq(val,VALUE_MIN)
544 #define value_max_p(val) value_eq(val,VALUE_MAX)
545 #define value_notmin_p(val) value_ne(val,VALUE_MIN)
546 #define value_notmax_p(val) value_ne(val,VALUE_MAX)
548 #endif /* 'Value' set to |longlong|long|float|char *|int */
551 /* *********************** PROTECTED MULTIPLICATION ********************** */
553 #include "arithmetic_errors.h"
555 /* (|v| < MAX / |w|) => v*w is okay
556 * I could check ((v*w)/w)==v but a tmp would be useful
558 #define value_protected_hard_idiv_multiply(v,w,throw) \
559 ((value_zero_p(w) || value_zero_p(v))? VALUE_ZERO: \
560 value_lt(value_abs(v),value_div(VALUE_MAX,value_abs(w)))? \
561 value_direct_multiply(v,w): (throw, VALUE_NAN))
563 /* is a software idiv is assumed, quick check performed first
565 #if defined(LINEAR_VALUE_ASSUME_SOFTWARE_IDIV)
566 #define value_protected_multiply(v,w,throw) \
567 ((value_le(v,VALUE_SQRT_MAX) && value_le(w,VALUE_SQRT_MAX) && \
568 value_ge(v,VALUE_SQRT_MIN) && value_ge(w,VALUE_SQRT_MIN))? \
569 value_direct_multiply(v,w): value_protected_hard_idiv_multiply(v,w,throw))
570 #else
571 #define value_protected_multiply(v,w,throw) \
572 value_protected_hard_idiv_multiply(v,w,throw)
573 #endif
575 /* protected versions
577 #define value_protected_mult(v,w) \
578 value_protected_multiply(v,w,THROW(overflow_error))
579 #define value_protected_product(v,w) \
580 v=value_protected_mult(v,w)
582 /* whether the default is protected or not
583 * this define makes no sense any more... well, doesn't matter. FC.
585 #if defined(LINEAR_VALUE_PROTECT_MULTIPLY)
586 #define value_mult(v,w) value_protected_mult(v,w)
587 #define value_product(v,w) value_protected_product(v,w)
588 #else
590 /* I do enforce the protection whatever requested:-)
591 * prints out a message and throws the exception, hoping
592 * that some valid CATCH waits for it upwards.
594 #define value_mult(v,w) \
595 value_protected_multiply(v,w, \
596 (fprintf(stderr,"[value_mult] value overflow!\n"),THROW(overflow_error)))
597 #define value_product(v,w) v=value_mult(v,w)
599 /* was:
600 * #define value_mult(v,w) value_direct_multiply(v,w)
601 * #define value_product(v,w) value_direct_product(v,w)
602 * could be: protected versions...
604 #endif
606 /******************************************************* STATIC VALUE DEBUG */
608 /* LINEAR_VALUE_IS_CHARS is used for type checking.
609 * some operations are not allowed on (char*), thus
610 * they are switched to some other operation here...
612 #if defined(LINEAR_VALUE_IS_CHARS)
613 #define value_fake_binary(v1,v2) ((Value)((v1).i+(v2).i))
614 #define value_bool_binary(v1,v2) ((int)((v1).i+(v2).i))
615 #undef float_to_value
616 #define float_to_value(f) ((Value)f)
617 #undef double_to_value
618 #define double_to_value(f) ((Value)f)
619 #undef value_uminus
620 #define value_uminus(v) (v)
621 #undef value_mult
622 #define value_mult(v1,v2) value_fake_binary(v1,v2)
623 #undef value_mod
624 #define value_mod(v1,v2) value_fake_binary(v1,v2)
625 #undef value_ge
626 #define value_ge(v1,v2) value_bool_binary(v1,v2)
627 #undef value_gt
628 #define value_gt(v1,v2) value_bool_binary(v1,v2)
629 #undef value_le
630 #define value_le(v1,v2) value_bool_binary(v1,v2)
631 #undef value_lt
632 #define value_lt(v1,v2) value_bool_binary(v1,v2)
633 #undef value_ne
634 #define value_ne(v1,v2) value_bool_binary(v1,v2)
635 #undef value_eq
636 #define value_eq(v1,v2) value_bool_binary(v1,v2)
637 #undef value_plus
638 #define value_plus(v1,v2) value_fake_binary(v1,v2)
639 #undef value_minus
640 #define value_minus(v1,v2) value_fake_binary(v1,v2)
641 #undef value_pdiv
642 #define value_pdiv(v1,v2) value_fake_binary(v1,v2)
643 #undef value_div
644 #define value_div(v1,v2) value_fake_binary(v1,v2)
645 #undef value_mod
646 #define value_mod(v1,v2) value_fake_binary(v1,v2)
647 #undef value_addto
648 #define value_addto(v1,v2) value_assign(v1,value_plus(v1,v2))
649 #undef value_subtract
650 #define value_subtract(v1,v2) value_addto(v1,v2)
651 #undef value_product
652 #define value_product(v1,v2) value_addto(v1,v2)
653 #undef value_modulus
654 #define value_modulus(v1,v2) value_addto(v1,v2)
655 #undef value_division
656 #define value_division(v1,v2) value_addto(v1,v2)
657 #undef value_divexact
658 #define value_divexact(v1,v2) value_addto(v1,v2)
659 #undef value_increment
660 #define value_increment(v) value_addto(v,VALUE_ONE)
661 #undef value_decrement
662 #define value_decrement(v) value_addto(v,VALUE_MONE)
663 #undef value_orto
664 #define value_orto(ref,val) value_addto(v1,v2)
665 #undef value_andto
666 #define value_andto(ref,val) value_addto(v1,v2)
667 #undef value_or
668 #define value_or(v1,v2) value_fake_binary(v1,v2)
669 #undef value_and
670 #define value_and(v1,v2) value_fake_binary(v1,v2)
671 #undef value_lshift
672 #define value_lshift(v1,v2) value_fake_binary(v1,v2)
673 #undef value_rshift
674 #define value_rshift(v1,v2) value_fake_binary(v1,v2)
675 #endif
677 /* for backward compatibility */
678 #define value_substract(ref,val1,val2) (value_subtract((ref),(val1),(val2)))
680 /* valeur absolue
682 #ifndef ABS
683 #define ABS(x) (((x)>=0) ? (x) : -(x))
684 #endif
686 /* minimum et maximum
687 * if they are defined somewhere else, they are very likely
688 * to be defined the same way. Thus the previous def is not overwritten.
690 #ifndef MIN
691 #define MIN(x,y) (((x)>=(y))?(y):(x))
692 #endif
693 #ifndef MAX
694 #define MAX(x,y) (((x)>=(y))?(x):(y))
695 #endif
697 /* signe d'un entier: -1, 0 ou 1 */
698 #define SIGN(x) (((x)>0)? 1 : ((x)==0? 0 : -1))
700 /* division avec reste toujours positif
701 * basee sur les equations:
702 * a/(-b) = - (a/b)
703 * (-a)/b = - ((a+b-1)/b)
704 * ou a et b sont des entiers positifs
706 #define DIVIDE(x,y) ((y)>0? POSITIVE_DIVIDE(x,y) : \
707 -POSITIVE_DIVIDE((x),(-(y))))
709 /* division avec reste toujours positif quand y est positif: assert(y>=0) */
710 #define POSITIVE_DIVIDE(x,y) ((x)>0 ? (x)/(y) : - (-(x)+(y)-1)/(y))
712 /* modulo a resultat toujours positif */
713 #define MODULO(x,y) ((y)>0 ? POSITIVE_MODULO(x,y) : POSITIVE_MODULO(-x,-y))
715 /* modulo par rapport a un nombre positif: assert(y>=0)
717 * Ce n'est pas la macro la plus efficace que j'aie jamais ecrite: il faut
718 * faire, dans le pire des cas, deux appels a la routine .rem, qui n'est
719 * surement pas plus cablee que la division ou la multiplication
721 #define POSITIVE_MODULO(x,y) ((x) > 0 ? (x)%(y) : \
722 ((x)%(y) == 0 ? 0 : ((y)-(-(x))%(y))))
724 /* errors.c */
725 extern unsigned int overflow_error;
726 extern unsigned int simplex_arithmetic_error;
727 extern unsigned int user_exception_error;
728 extern unsigned int parser_exception_error;
729 extern unsigned int any_exception_error;
730 extern unsigned int the_last_just_thrown_exception;
731 extern void dump_exception_stack_to_file(FILE * /*f*/);
732 extern void dump_exception_stack(void);
733 extern jmp_buf *push_exception_on_stack(int /*what*/, const char * /*function*/, const char * /*file*/, int /*line*/);
734 extern void pop_exception_from_stack(int /*what*/, const char * /*function*/, const char * /*file*/, int /*line*/);
735 extern void throw_exception(int /*what*/, const char * /*function*/, const char * /*file*/, int /*line*/);
737 #endif /* arithmetique_header_included */