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