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