long long int string format for win32
[polylib.git] / source / arith / arithmetique.h
blob7444744d00ddb5d604a5de5694c7ca0b8026ea2c
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.5 2005/02/28 13:32:25 loechner Exp $
9 * Francois Irigoin, mai 1989
11 * Modifications
12 * - reprise de DIVIDE qui etait faux (Remi Triolet, Francois Irigoin,
13 * april 90)
14 * - simplification de POSITIVE_DIVIDE par suppression d'un modulo
17 /* We would like linear to be generic about the "integer" type used
18 * to represent integer values. Thus Value is defined here. It should
19 * be changed to "int" "long" or "long long". In an ideal world,
20 * any source modification should be limited to this package.
22 * Indeed, we cannot switch easily to bignums that need constructors
23 * dans destructors... That would lead to too many modifications...
24 * C++ would make things easier and cleaner...
26 * Fabien COELHO
29 #include <stdio.h>
30 #include <limits.h> /* Included for getting constants: INT_MAX, etc.. */
32 #ifdef GNUMP
33 #include <gmp.h>
34 #endif
36 /*
37 # #### # # #### # #### # # ####
38 # # # ## # # # # # # ## # # #
39 # # # # # # # # # # # # # #
40 # # # # # # # ### # # # # # # # ###
41 # # # # ## # # # # # # ## # #
42 ###### #### # # #### ###### #### # # ####
46 /*
47 * Constants like LONG_LONG_MAX are not defined with ansi options, so they are
48 * defined here.
49 */
51 #ifndef LONG_LONG_MAX
53 /* would fix on solaris:
54 * #define LONG_LONG_MAX LLONG_MAX
55 * #define LONG_LONG_MIN LLONG_MIN
58 #ifndef __LONG_LONG_MAX__
59 #define __LONG_LONG_MAX__ 9223372036854775807LL
60 #endif
61 #undef LONG_LONG_MAX
62 #define LONG_LONG_MAX __LONG_LONG_MAX__
63 #undef LONG_LONG_MIN
64 #define LONG_LONG_MIN (-LONG_LONG_MAX-1)
65 #undef ULONG_LONG_MAX
66 #define ULONG_LONG_MAX (LONG_LONG_MAX * 2ULL + 1)
67 #endif
69 #if defined(LINEAR_VALUE_IS_LONGLONG)
71 #define LINEAR_VALUE_STRING "long long int"
72 typedef long long int Value;
73 #if defined(WIN32) && !defined(unix)
74 /* Mingw or Windows need an incompatible format string. */
75 # define VALUE_FMT "%I64d"
76 #else
77 # define VALUE_FMT "%lld"
78 #endif
79 #define VALUE_CONST(val) (val##LL)
81 /*
82 * CAUTION! 'VALUE_MIN' is defined as 'LONG_LONG_MIN +1' so as to preserve the
83 * symmetry (-min==max) and to have a NAN value. FC
84 */
86 #define VALUE_NAN LONG_LONG_MIN
87 #define VALUE_MIN (LONG_LONG_MIN+1LL)
88 #define VALUE_MAX LONG_LONG_MAX
89 #define VALUE_SQRT_MIN long_to_value(LONG_MIN)
90 #define VALUE_SQRT_MAX long_to_value(LONG_MAX)
91 #define VALUE_ZERO (0LL)
92 #define VALUE_ONE (1LL)
93 #define VALUE_MONE (-1LL)
95 #define VALUE_TO_LONG(val) \
96 ((long)((val)>(Value)LONG_MIN&&(val)<=(Value)LONG_MAX)?\
97 (val):(THROW(overflow_error), LONG_MIN))
99 #define VALUE_TO_INT(val) \
100 ((int)((val)>(Value)INT_MIN&&(val)<=(Value)INT_MAX)?\
101 (val):(THROW(overflow_error), INT_MIN))
103 #define VALUE_TO_DOUBLE(val) ((double)(val))
105 /* #define VALUE_TO_FLOAT(val) ((float)(val)): Doesn't seem to work with gcc */
106 #define VALUE_TO_FLOAT(val) ((float)((int)(val)))
108 /* end LINEAR_VALUE_IS_LONGLONG */
112 # #### # # ####
113 # # # ## # # #
114 # # # # # # #
115 # # # # # # # ###
116 # # # # ## # #
117 ###### #### # # ####
121 #elif defined(LINEAR_VALUE_IS_LONG)
123 #define LINEAR_VALUE_STRING "long int"
124 typedef long Value;
125 #define VALUE_FMT "%ld"
126 #define VALUE_CONST(val) (val##L)
127 #define VALUE_NAN LONG_MIN
128 #define VALUE_MIN (LONG_MIN+1L)
129 #define VALUE_MAX LONG_MAX
130 #define VALUE_ZERO 0L
131 #define VALUE_ONE 1L
132 #define VALUE_MONE -1L
133 #define VALUE_TO_LONG(val) (val)
134 #define VALUE_TO_INT(val) ((int)(val))
135 #define VALUE_TO_FLOAT(val) ((float)(val))
136 #define VALUE_TO_DOUBLE(val) ((double)(val))
138 /* end LINEAR_VALUE_IS_LONG */
141 ###### # #### ## #####
142 # # # # # # #
143 ##### # # # # # #
144 # # # # ###### #
145 # # # # # # #
146 # ###### #### # # #
151 #elif defined(LINEAR_VALUE_IS_FLOAT)
153 #define LINEAR_VALUE_STRING "float"
154 typedef float Value;
155 #define VALUE_FMT "%f"
156 #define VALUE_CONST(val) (val)
157 #define VALUE_MIN FLOAT_MIN
158 #define VALUE_MAX FLOAT_MAX
159 #define VALUE_ZERO 0.0
160 #define VALUE_ONE 1.0
161 #define VALUE_MONE -1.0
162 #define VALUE_TO_LONG(val) ((long)(val))
163 #define VALUE_TO_INT(val) ((int)(val))
164 #define VALUE_TO_FLOAT(val) ((float)(val))
165 #define VALUE_TO_DOUBLE(val) ((double)(val))
169 /* end LINEAR_VALUE_IS_FLOAT */
172 #### # # ## ##### # #
173 # # # # # # # # # #
174 # ###### # # # # #######
175 # # # ###### ##### # #
176 # # # # # # # # # #
177 #### # # # # # #
181 /* Char version is used to detect invalid assignments */
183 #elif defined(LINEAR_VALUE_IS_CHARS)
185 #define LINEAR_VALUE_STRING "char"
186 typedef union { char *s; long l; int i; float f; double d;} Value;
187 #define VALUE_FMT "%s"
188 #define VALUE_CONST(val) ((Value)(val))
189 #define VALUE_NAN ((Value)(long)0xdadeebee)
190 #define VALUE_MIN ((Value)(long)0xdeadbeef)
191 #define VALUE_MAX ((Value)(long)0xfeedabee)
192 #define VALUE_ZERO ((Value)0)
193 #define VALUE_ONE ((Value)1)
194 #define VALUE_MONE ((Value)-1)
195 #define VALUE_TO_LONG(val) (val.l)
196 #define VALUE_TO_INT(val) (val.i)
197 #define VALUE_TO_FLOAT(val) (val.f)
198 #define VALUE_TO_DOUBLE(val) (val.d)
200 /* end LINEAR_VALUE_IS_CHARS */
203 # # # #####
204 # ## # #
205 # # # # #
206 # # # # #
207 # # ## #
208 # # # #
212 #elif defined(LINEAR_VALUE_IS_INT)
214 #define LINEAR_VALUE_STRING "int"
215 typedef int Value;
216 #define VALUE_FMT "%d"
217 #define VALUE_CONST(val) (val)
218 #define VALUE_NAN INT_MIN
219 #define VALUE_MIN (INT_MIN+1)
220 #define VALUE_MAX INT_MAX
221 #define VALUE_ZERO 0
222 #define VALUE_ONE 1
223 #define VALUE_MONE -1
224 #define VALUE_TO_LONG(val) ((long)(val))
225 #define VALUE_TO_INT(val) ((int)(val))
226 #define VALUE_TO_FLOAT(val) ((float)(val))
227 #define VALUE_TO_DOUBLE(val) ((double)(val))
229 /* end LINEAR_VALUE_IS_INT */
231 #else /* If defined(GNUMP) */
233 #define LINEAR_VALUE_STRING "gmp"
234 typedef mpz_t Value;
235 #define VALUE_FMT "%s"
237 /* don't use these, use value_set_si instead ! */
238 #undef VALUE_ZERO
239 #undef VALUE_ONE
240 #undef VALUE_MONE
241 #define VALUE_TO_LONG(val) (mpz_get_si(val))
242 #define VALUE_TO_INT(val) ((int)mpz_get_si(val))
243 #define VALUE_TO_FLOAT(val) ((float)((int)mpz_get_si(val)))
244 #define VALUE_TO_DOUBLE(val) (mpz_get_d(val))
246 #endif
248 /* ***************** MACROS FOR MANIPULATING VALUES ******************** */
250 #if defined(GNUMP)
252 /* Basic macros */
254 #define value_init(val) (mpz_init((val)))
255 #define value_assign(v1,v2) (mpz_set((v1),(v2)))
256 #define value_set_si(val,i) (mpz_set_si((val),(i)))
257 #define value_set_double(val,d)(mpz_set_d((val),(d)))
258 #define value_clear(val) (mpz_clear((val)))
259 #define value_read(val,str) (mpz_set_str((val),(str),10))
260 #define value_print(Dst,fmt,val) {char *str; str = mpz_get_str(0,10,(val)); \
261 fprintf((Dst),(fmt),str); free(str); \
263 #define value_swap(val1,val2) {mpz_t tmp; mpz_init_set(tmp,(val1)); \
264 mpz_set((val1),(val2)); mpz_set((val2),tmp); \
265 mpz_clear(tmp); \
268 /* Boolean operators on 'Value' */
270 #define value_eq(v1,v2) (mpz_cmp((v1),(v2)) == 0)
271 #define value_ne(v1,v2) (mpz_cmp((v1),(v2)) != 0)
272 #define value_gt(v1,v2) (mpz_cmp((v1),(v2)) > 0)
273 #define value_ge(v1,v2) (mpz_cmp((v1),(v2)) >= 0)
274 #define value_lt(v1,v2) (mpz_cmp((v1),(v2)) < 0)
275 #define value_le(v1,v2) (mpz_cmp((v1),(v2)) <= 0)
277 /* Trian operators on 'Value' */
279 #define value_sign(val) (mpz_sgn(val))
280 #define value_compare(v1,v2) (mpz_cmp((v1),(v2)))
282 /* Binary operations on 'Value' */
284 #define value_addto(ref,val1,val2) (mpz_add((ref),(val1),(val2)))
285 #define value_add_int(ref,val,vint) (mpz_add_ui((ref),(val),(long)(vint)))
286 #define value_increment(ref,val) (mpz_add_ui((ref),(val),1))
287 #define value_multiply(ref,val1,val2) (mpz_mul((ref),(val1),(val2)))
288 #define value_substract(ref,val1,val2) (mpz_sub((ref),(val1),(val2)))
289 #define value_sub_int(ref,val,vint) (mpz_sub_ui((ref),(val),(long)(vint)))
290 #define value_decrement(ref,val) (mpz_sub_ui((ref),(val),1))
291 #define value_division(ref,val1,val2) (mpz_tdiv_q((ref),(val1),(val2)))
292 #define value_modulus(ref,val1,val2) (mpz_tdiv_r((ref),(val1),(val2)))
293 #define value_pdivision(ref,val1,val2) (mpz_fdiv_q((ref),(val1),(val2)))
294 #define value_pmodulus(ref,val1,val2) (mpz_fdiv_r((ref),(val1),(val2)))
295 #define value_oppose(ref,val) (mpz_neg((ref),(val)))
296 #define value_absolute(ref,val) (mpz_abs((ref),(val)))
297 #define value_minimum(ref,val1,val2) (value_le((val1),(val2)) ? \
298 mpz_set((ref),(val1)) : \
299 mpz_set((ref),(val2)))
300 #define value_maximum(ref,val1,val2) (value_ge((val1),(val2)) ? \
301 mpz_set((ref),(val1)) : \
302 mpz_set((ref),(val2)))
303 #define value_orto(ref,val1,val2) (mpz_ior((ref),(val1),(val2)))
304 #define value_andto(ref,val1,val2) (mpz_and((ref),(val1),(val2)))
306 /* Conditional operations on 'Value' */
308 #define value_pos_p(val) (mpz_sgn(val) > 0)
309 #define value_neg_p(val) (mpz_sgn(val) < 0)
310 #define value_posz_p(val) (mpz_sgn(val) >= 0)
311 #define value_negz_p(val) (mpz_sgn(val) <= 0)
312 #define value_zero_p(val) (mpz_sgn(val) == 0)
313 #define value_notzero_p(val) (mpz_sgn(val) != 0)
314 #define value_one_p(val) (mpz_cmp_si(val,1) == 0)
315 #define value_notone_p(val) (mpz_cmp_si(val,1) != 0)
316 #define value_mone_p(val) (mpz_cmp_si(val,-1) ==0)
317 #define value_notmone_p(val) (mpz_cmp_si(val,-1) !=0)
319 /* ************************************************************************* */
321 #else /* 'Value' set to longlong|long|float|char *|int */
322 /* Basic Macros */
324 #define value_init(val) ((val) = 0)
325 #define value_assign(v1,v2) ((v1) = (v2))
326 #define value_set_si(val,i) ((val) = (Value)(i))
327 #define value_set_double(val,d) ((val) = (Value)(d))
328 #define value_clear(val) ((val) = 0)
329 #define value_read(val,str) (sscanf((str),VALUE_FMT,&(val)))
330 #define value_print(Dst,fmt,val) (fprintf((Dst),(fmt),(val)))
331 #define value_swap(v1,v2) {Value tmp; tmp = v2; \
332 v2 = v1; v1 = tmp; \
334 /* Cast to 'Value' */
336 #define int_to_value(i) ((Value)(i))
337 #define long_to_value(l) ((Value)(l))
338 #define float_to_value(f) ((Value)(f))
339 #define double_to_value(d) ((Value)(d))
341 /* Boolean operators on 'Value' */
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))
350 /* Trian operators on 'Value' */
352 #define value_sign(v) (value_eq(v,VALUE_ZERO)?0:value_lt(v,VALUE_ZERO)?-1:1)
353 #define value_compare(v1,v2) (value_eq(v1,v2)?0:value_lt(v1,v2)?-1:1)
355 /* Binary operators on 'Value' */
357 #define value_plus(v1,v2) ((v1)+(v2))
358 #define value_div(v1,v2) ((v1)/(v2))
359 #define value_mod(v1,v2) ((v1)%(v2))
360 #define value_direct_multiply(v1,v2) ((v1)*(v2)) /* direct! */
361 #define value_minus(v1,v2) ((v1)-(v2))
362 #define value_pdiv(v1,v2) (divide((v1),(v2)))
363 #define value_pmod(v1,v2) (modulo((v1),(v2)))
364 #define value_min(v1,v2) (value_le((v1),(v2))? (v1): (v2))
365 #define value_max(v1,v2) (value_ge((v1),(v2))? (v1): (v2))
366 #define value_or(v1,v2) ((v1)|(v2))
367 #define value_and(v1,v2) ((v1)&(v2))
368 #define value_lshift(v1,v2) ((v1)<<(v2))
369 #define value_rshift(v1,v2) ((v1)>>(v2))
371 /* Binary operations on 'Value' */
373 #define value_addto(ref,val1,val2) ((ref) = (val1)+(val2))
374 #define value_add_int(ref,val,vint) ((ref) = (val)+(Value)(vint))
375 #define value_increment(ref,val) ((ref) = (val)+VALUE_ONE)
376 #define value_direct_product(ref,val1,val2) ((ref) = (val1)*(val2)) /* direct! */
377 #define value_multiply(ref,val1,val2) ((ref) = value_mult((val1),(val2)))
378 #define value_substract(ref,val1,val2) ((ref) = (val1)-(val2))
379 #define value_sub_int(ref,val,vint) ((ref) = (val)-(Value)(vint))
380 #define value_decrement(ref,val) ((ref) = (val)-VALUE_ONE)
381 #define value_division(ref,val1,val2) ((ref) = (val1)/(val2))
382 #define value_modulus(ref,val1,val2) ((ref) = (val1)%(val2))
383 #define value_pdivision(ref,val1,val2) ((ref) = value_pdiv((val1),(val2)))
384 #define value_pmodulus(ref,val1,val2) ((ref) = value_pmod((val1),(val2)))
385 #define value_oppose(ref,val) ((ref) = value_uminus((val)))
386 #define value_absolute(ref,val) ((ref) = value_abs((val)))
387 #define value_minimum(ref,val1,val2) ((ref) = value_min((val1),(val2)))
388 #define value_maximum(ref,val1,val2) ((ref) = value_max((val1),(val2)))
389 #define value_orto(ref,val1,val2) ((ref) = (val1)|(val2))
390 #define value_andto(ref,val1,val2) ((ref) = (val1)&(val2))
392 /* Unary operators on 'Value' */
394 #define value_uminus(val) (-(val))
395 #define value_not(val) (~(val))
396 #define value_abs(val) (value_posz_p(val)? \
397 (val) : \
398 (value_ne((val), VALUE_NAN) ? \
399 value_uminus(val) : \
400 (THROW (overflow_error), VALUE_NAN )))
402 /* Conditional operations on 'Value' */
404 #define value_pos_p(val) value_gt(val,VALUE_ZERO)
405 #define value_neg_p(val) value_lt(val,VALUE_ZERO)
406 #define value_posz_p(val) value_ge(val,VALUE_ZERO)
407 #define value_negz_p(val) value_le(val,VALUE_ZERO)
408 #define value_zero_p(val) value_eq(val,VALUE_ZERO)
409 #define value_notzero_p(val) value_ne(val,VALUE_ZERO)
410 #define value_one_p(val) value_eq(val,VALUE_ONE)
411 #define value_notone_p(val) value_ne(val,VALUE_ONE)
412 #define value_mone_p(val) value_eq(val,VALUE_MONE)
413 #define value_notmone_p(val) value_ne(val,VALUE_MONE)
414 #define value_min_p(val) value_eq(val,VALUE_MIN)
415 #define value_max_p(val) value_eq(val,VALUE_MAX)
416 #define value_notmin_p(val) value_ne(val,VALUE_MIN)
417 #define value_notmax_p(val) value_ne(val,VALUE_MAX)
419 #endif /* 'Value' set to |longlong|long|float|char *|int */
422 /* *********************** PROTECTED MULTIPLICATION ********************** */
424 #include "arithmetic_errors.h"
426 /* (|v| < MAX / |w|) => v*w is okay
427 * I could check ((v*w)/w)==v but a tmp would be useful
429 #define value_protected_hard_idiv_multiply(v,w,throw) \
430 ((value_zero_p(w) || value_zero_p(v))? VALUE_ZERO: \
431 value_lt(value_abs(v),value_div(VALUE_MAX,value_abs(w)))? \
432 value_direct_multiply(v,w): (throw, VALUE_NAN))
434 /* is a software idiv is assumed, quick check performed first
436 #if defined(LINEAR_VALUE_ASSUME_SOFTWARE_IDIV)
437 #define value_protected_multiply(v,w,throw) \
438 ((value_le(v,VALUE_SQRT_MAX) && value_le(w,VALUE_SQRT_MAX) && \
439 value_ge(v,VALUE_SQRT_MIN) && value_ge(w,VALUE_SQRT_MIN))? \
440 value_direct_multiply(v,w): value_protected_hard_idiv_multiply(v,w,throw))
441 #else
442 #define value_protected_multiply(v,w,throw) \
443 value_protected_hard_idiv_multiply(v,w,throw)
444 #endif
446 /* protected versions
448 #define value_protected_mult(v,w) \
449 value_protected_multiply(v,w,THROW(overflow_error))
450 #define value_protected_product(v,w) \
451 v=value_protected_mult(v,w)
453 /* whether the default is protected or not
454 * this define makes no sense any more... well, doesn't matter. FC.
456 #if defined(LINEAR_VALUE_PROTECT_MULTIPLY)
457 #define value_mult(v,w) value_protected_mult(v,w)
458 #define value_product(v,w) value_protected_product(v,w)
459 #else
461 /* I do enforce the protection whatever requested:-)
462 * prints out a message and throws the exception, hoping
463 * that some valid CATCH waits for it upwards.
465 #define value_mult(v,w) \
466 value_protected_multiply(v,w, \
467 (fprintf(stderr,"[value_mult] value overflow!\n"),THROW(overflow_error)))
468 #define value_product(v,w) v=value_mult(v,w)
470 /* was:
471 * #define value_mult(v,w) value_direct_multiply(v,w)
472 * #define value_product(v,w) value_direct_product(v,w)
473 * could be: protected versions...
475 #endif
477 /******************************************************* STATIC VALUE DEBUG */
479 /* LINEAR_VALUE_IS_CHARS is used for type checking.
480 * some operations are not allowed on (char*), thus
481 * they are switched to some other operation here...
483 #if defined(LINEAR_VALUE_IS_CHARS)
484 #define value_fake_binary(v1,v2) ((Value)((v1).i+(v2).i))
485 #define value_bool_binary(v1,v2) ((int)((v1).i+(v2).i))
486 #undef float_to_value
487 #define float_to_value(f) ((Value)f)
488 #undef double_to_value
489 #define double_to_value(f) ((Value)f)
490 #undef value_uminus
491 #define value_uminus(v) (v)
492 #undef value_mult
493 #define value_mult(v1,v2) value_fake_binary(v1,v2)
494 #undef value_mod
495 #define value_mod(v1,v2) value_fake_binary(v1,v2)
496 #undef value_ge
497 #define value_ge(v1,v2) value_bool_binary(v1,v2)
498 #undef value_gt
499 #define value_gt(v1,v2) value_bool_binary(v1,v2)
500 #undef value_le
501 #define value_le(v1,v2) value_bool_binary(v1,v2)
502 #undef value_lt
503 #define value_lt(v1,v2) value_bool_binary(v1,v2)
504 #undef value_ne
505 #define value_ne(v1,v2) value_bool_binary(v1,v2)
506 #undef value_eq
507 #define value_eq(v1,v2) value_bool_binary(v1,v2)
508 #undef value_plus
509 #define value_plus(v1,v2) value_fake_binary(v1,v2)
510 #undef value_minus
511 #define value_minus(v1,v2) value_fake_binary(v1,v2)
512 #undef value_pdiv
513 #define value_pdiv(v1,v2) value_fake_binary(v1,v2)
514 #undef value_div
515 #define value_div(v1,v2) value_fake_binary(v1,v2)
516 #undef value_mod
517 #define value_mod(v1,v2) value_fake_binary(v1,v2)
518 #undef value_addto
519 #define value_addto(v1,v2) value_assign(v1,value_plus(v1,v2))
520 #undef value_substract
521 #define value_substract(v1,v2) value_addto(v1,v2)
522 #undef value_product
523 #define value_product(v1,v2) value_addto(v1,v2)
524 #undef value_modulus
525 #define value_modulus(v1,v2) value_addto(v1,v2)
526 #undef value_division
527 #define value_division(v1,v2) value_addto(v1,v2)
528 #undef value_increment
529 #define value_increment(v) value_addto(v,VALUE_ONE)
530 #undef value_decrement
531 #define value_decrement(v) value_addto(v,VALUE_MONE)
532 #undef value_orto
533 #define value_orto(ref,val) value_addto(v1,v2)
534 #undef value_andto
535 #define value_andto(ref,val) value_addto(v1,v2)
536 #undef value_or
537 #define value_or(v1,v2) value_fake_binary(v1,v2)
538 #undef value_and
539 #define value_and(v1,v2) value_fake_binary(v1,v2)
540 #undef value_lshift
541 #define value_lshift(v1,v2) value_fake_binary(v1,v2)
542 #undef value_rshift
543 #define value_rshift(v1,v2) value_fake_binary(v1,v2)
544 #endif
547 /* valeur absolue
549 #ifndef ABS
550 #define ABS(x) (((x)>=0) ? (x) : -(x))
551 #endif
553 /* minimum et maximum
554 * if they are defined somewhere else, they are very likely
555 * to be defined the same way. Thus the previous def is not overwritten.
557 #ifndef MIN
558 #define MIN(x,y) (((x)>=(y))?(y):(x))
559 #endif
560 #ifndef MAX
561 #define MAX(x,y) (((x)>=(y))?(x):(y))
562 #endif
564 /* signe d'un entier: -1, 0 ou 1 */
565 #define SIGN(x) (((x)>0)? 1 : ((x)==0? 0 : -1))
567 /* division avec reste toujours positif
568 * basee sur les equations:
569 * a/(-b) = - (a/b)
570 * (-a)/b = - ((a+b-1)/b)
571 * ou a et b sont des entiers positifs
573 #define DIVIDE(x,y) ((y)>0? POSITIVE_DIVIDE(x,y) : \
574 -POSITIVE_DIVIDE((x),(-(y))))
576 /* division avec reste toujours positif quand y est positif: assert(y>=0) */
577 #define POSITIVE_DIVIDE(x,y) ((x)>0 ? (x)/(y) : - (-(x)+(y)-1)/(y))
579 /* modulo a resultat toujours positif */
580 #define MODULO(x,y) ((y)>0 ? POSITIVE_MODULO(x,y) : POSITIVE_MODULO(-x,-y))
582 /* modulo par rapport a un nombre positif: assert(y>=0)
584 * Ce n'est pas la macro la plus efficace que j'aie jamais ecrite: il faut
585 * faire, dans le pire des cas, deux appels a la routine .rem, qui n'est
586 * surement pas plus cablee que la division ou la multiplication
588 #define POSITIVE_MODULO(x,y) ((x) > 0 ? (x)%(y) : \
589 ((x)%(y) == 0 ? 0 : ((y)-(-(x))%(y))))
591 /* Pour la recherche de performance, selection d'une implementation
592 * particuliere des fonctions
595 #define divide(a,b) DIVIDE(a,b)
597 #define modulo(a,b) MODULO(a,b)
599 typedef struct {Value num, den; int numero ; } frac ;
600 typedef struct col{int taille, existe ; frac *colonne ;} tableau ;
602 /* errors.c */
603 extern unsigned int overflow_error;
604 extern unsigned int simplex_arithmetic_error;
605 extern unsigned int user_exception_error;
606 extern unsigned int parser_exception_error;
607 extern unsigned int any_exception_error;
608 extern unsigned int the_last_just_thrown_exception;
609 extern int linear_exception_debug_mode;
610 extern void dump_exception_stack_to_file(FILE * /*f*/);
611 extern void dump_exception_stack(void);
612 extern jmp_buf *push_exception_on_stack(int /*what*/, char * /*function*/, char * /*file*/, int /*line*/);
613 extern void pop_exception_from_stack(int /*what*/, char * /*function*/, char * /*file*/, int /*line*/);
614 extern void throw_exception(int /*what*/, const char * /*function*/, const char * /*file*/, int /*line*/);
616 #endif /* arithmetique_header_included */