PIPS
arithmetique-local.h
Go to the documentation of this file.
1 /*
2 
3  $Id: arithmetique-local.h 1673 2023-07-10 12:21:00Z coelho $
4 
5  Copyright 1989-2016 MINES ParisTech
6 
7  This file is part of Linear/C3 Library.
8 
9  Linear/C3 Library is free software: you can redistribute it and/or modify it
10  under the terms of the GNU Lesser General Public License as published by
11  the Free Software Foundation, either version 3 of the License, or
12  any later version.
13 
14  Linear/C3 Library is distributed in the hope that it will be useful, but
15  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16  FITNESS FOR A PARTICULAR PURPOSE.
17 
18  See the GNU Lesser General Public License for more details.
19 
20  You should have received a copy of the GNU Lesser General Public License
21  along with Linear/C3 Library. If not, see <http://www.gnu.org/licenses/>.
22 
23 */
24 
25 /* package arithmetique
26  *
27  * Francois Irigoin, mai 1989
28  *
29  * Modifications
30  * - reprise de DIVIDE qui etait faux (Remi Triolet, Francois Irigoin,
31  * april 90)
32  * - simplification de POSITIVE_DIVIDE par suppression d'un modulo
33  */
34 
35 /* We would like linear to be generic about the "integer" type used
36  * to represent integer values. Thus Value is defined here. It should
37  * be changed to "int" "long" or "long long". In an ideal world,
38  * any source modification should be limited to this package.
39  *
40  * Indeed, we cannot switch easily to bignums that need constructors
41  * dans destructors... That would lead to too many modifications...
42  * C++ would make things easier and cleaner...
43  *
44  * Fabien COELHO
45  */
46 
47 /* for FILE *
48  */
49 #include <stdio.h>
50 
51 /* to be included for _MIN and _MAX: #include <limits.h>
52  */
53 #include <limits.h>
54 #include "boolean.h"
55 
56 /******************************************************** TIMEOUT MANAGEMENT */
57 
58 # if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
59 # define CURRENT_FUNCTION __func__
60 # else
61 # if defined(__GNUC__)
62 # define CURRENT_FUNCTION __FUNCTION__
63 # else
64 # define CURRENT_FUNCTION "<unknown>"
65 # endif // __GNUC__
66 # endif // C99
67 
68 #define PUSH_TIMEOUT_ENV(env) \
69  push_timeout_env(env, CURRENT_FUNCTION, __FILE__, __LINE__)
70 
71 #define POP_TIMEOUT_ENV(env) \
72  pop_timeout_env(env, CURRENT_FUNCTION, __FILE__, __LINE__)
73 
74 #define PUSH_TIMEOUT(delay) \
75  push_timeout(delay, CURRENT_FUNCTION, __FILE__, __LINE__)
76 
77 #define POP_TIMEOUT() \
78  pop_timeout(CURRENT_FUNCTION, __FILE__, __LINE__)
79 
80 /* put there because I cannot have these constants with ansi options.
81  */
82 #ifndef LONG_LONG_MAX
83 
84 /* would fix on solaris:
85  * #define LONG_LONG_MAX LLONG_MAX
86  * #define LONG_LONG_MIN LLONG_MIN
87  */
88 
89 #ifndef __LONG_LONG_MAX__
90 #define __LONG_LONG_MAX__ 9223372036854775807LL
91 #endif
92 #undef LONG_LONG_MAX
93 #define LONG_LONG_MAX __LONG_LONG_MAX__
94 #undef LONG_LONG_MIN
95 #define LONG_LONG_MIN (-LONG_LONG_MAX-1)
96 #undef ULONG_LONG_MAX
97 #define ULONG_LONG_MAX (LONG_LONG_MAX * 2ULL + 1)
98 #endif
99 
100 /*
101  # ##### #####
102  # # # ##### ## # # # #
103  # ## # # # # # # #
104  # # # # # # ##### #####
105  # # # # # # # # #
106  # # ## # # # # #
107  # # # # ##### ####### #####
108  */
109 
110 #if defined(LINEAR_VALUE_IS_INT128)
111 // TODO
112 #error "not implemented yet"
113 
114 #include <inttypes.h>
115 #define LINEAR_VALUE_STRING "int128"
116 typedef __int128 Value;
117 #define VALUE_FMT "???"
118 #define VALUE_CONST(val) (val##LLL)
119 #define VALUE_NAN ???_MIN
120 /* CAUTION! the min is defined as hard-min+1 so as to preserve the
121  * symetry (-min==max) and to have a nan value. FC.
122  */
123 #define VALUE_MIN (???_MIN+1LL)
124 #define VALUE_MAX ???_MAX
125 #if defined(LINEAR_VALUE_ASSUME_SOFTWARE_IDIV) && \
126  defined(__SIZEOF_???__) && \
127  __SIZEOF_???__ != 8
128  #error "long long is expected to be 64-bit to use software idiv"
129 #endif
130 #define VALUE_SQRT_MIN ???LLL /* floor(sqrt(LONG_LONG_MAX)) */
131 #define VALUE_SQRT_MAX -???LLL
132 #define VALUE_ZERO (0LLL)
133 #define VALUE_ONE (1LLL)
134 #define VALUE_MONE (-1LLL)
135 /* I can just trust myself for this...
136  */
137 #define VALUE_TO_LONG(val) \
138  ((long)((val)>(Value)LONG_MIN&&(val)<=(Value)LONG_MAX)?\
139  (val):(THROW(overflow_error), LONG_MIN))
140 #define VALUE_TO_INT(val) \
141  ((int)((val)>(Value)INT_MIN&&(val)<=(Value)INT_MAX)?\
142  (val):(THROW(overflow_error), INT_MIN))
143 #define VALUE_TO_DOUBLE(val) ((double)(val))
144 #define VALUE_TO_FLOAT(val) ((float)((int)(val)))
145 
146 // end LINEAR_VALUE_IS_INT128
147 
148 
149 /*
150  # #### # # #### # #### # # ####
151  # # # ## # # # # # # ## # # #
152  # # # # # # # # # # # # # #
153  # # # # # # # ### # # # # # # # ###
154  # # # # ## # # # # # # ## # #
155  ###### #### # # #### ###### #### # # ####
156 
157  */
158 
159 #elif defined(LINEAR_VALUE_IS_LONGLONG)
160 #define LINEAR_VALUE_STRING "long long int"
161 typedef long long int Value;
162 #define VALUE_FMT "%lld"
163 #define VALUE_CONST(val) (val##LL)
164 #define VALUE_NAN LONG_LONG_MIN
165 /* CAUTION! the min is defined as hard-min+1 so as to preserve the
166  * symetry (-min==max) and to have a nan value. FC.
167  */
168 #define VALUE_MIN (LONG_LONG_MIN+1LL)
169 #define VALUE_MAX LONG_LONG_MAX
170 #if defined(LINEAR_VALUE_ASSUME_SOFTWARE_IDIV) && \
171  defined(__SIZEOF_LONG_LONG__) && \
172  __SIZEOF_LONG_LONG__ != 8
173  #error "long long is expected to be 64-bit to use software idiv"
174 #endif
175 #define VALUE_SQRT_MIN 3037000499LL /* floor(sqrt(LONG_LONG_MAX)) */
176 #define VALUE_SQRT_MAX -3037000499LL
177 #define VALUE_ZERO (0LL)
178 #define VALUE_ONE (1LL)
179 #define VALUE_MONE (-1LL)
180 /* I can just trust myself for this...
181  */
182 #define VALUE_TO_LONG(val) \
183  ((long)((val)>(Value)LONG_MIN&&(val)<=(Value)LONG_MAX)?\
184  (val):(THROW(overflow_error), LONG_MIN))
185 #define VALUE_TO_INT(val) \
186  ((int)((val)>(Value)INT_MIN&&(val)<=(Value)INT_MAX)?\
187  (val):(THROW(overflow_error), INT_MIN))
188 #define VALUE_TO_DOUBLE(val) ((double)(val))
189 /* FI: I do not understand why, but the first definition isn't working with gcc */
190 /* #define VALUE_TO_FLOAT(val) ((float)(val)) */
191 #define VALUE_TO_FLOAT(val) ((float)((int)(val)))
192 
193 /* end LINEAR_VALUE_IS_LONGLONG
194  */
195 
196 /*
197  # #### # # ####
198  # # # ## # # #
199  # # # # # # #
200  # # # # # # # ###
201  # # # # ## # #
202  ###### #### # # ####
203 
204  */
205 
206 #elif defined(LINEAR_VALUE_IS_LONG)
207 #define LINEAR_VALUE_STRING "long int"
208 typedef long Value;
209 #define VALUE_FMT "%ld"
210 #define VALUE_CONST(val) (val##L)
211 #define VALUE_NAN LONG_MIN
212 #define VALUE_MIN (LONG_MIN+1L)
213 #define VALUE_MAX LONG_MAX
214 #define VALUE_ZERO 0L
215 #define VALUE_ONE 1L
216 #define VALUE_MONE -1L
217 #define VALUE_TO_LONG(val) (val)
218 #define VALUE_TO_INT(val) ((int)(val))
219 #define VALUE_TO_FLOAT(val) ((float)(val))
220 #define VALUE_TO_DOUBLE(val) ((double)(val))
221 
222 /* end LINEAR_VALUE_IS_LONG
223  */
224 
225 /*
226  ###### # #### ## #####
227  # # # # # # #
228  ##### # # # # # #
229  # # # # ###### #
230  # # # # # # #
231  # ###### #### # # #
232 
233  */
234 /*
235 #elif defined(LINEAR_VALUE_IS_FLOAT)
236 #define LINEAR_VALUE_STRING "float"
237 typedef float Value;
238 #define VALUE_FMT "%f"
239 #define VALUE_CONST(val) (val)
240 #define VALUE_MIN FLOAT_MIN
241 #define VALUE_MAX FLOAT_MAX
242 #define VALUE_ZERO 0.0
243 #define VALUE_ONE 1.0
244 #define VALUE_MONE -1.0
245 #define VALUE_TO_LONG(val) ((long)(val))
246 #define VALUE_TO_INT(val) ((int)(val))
247 #define VALUE_TO_FLOAT(val) ((float)(val))
248 #define VALUE_TO_DOUBLE(val) ((double)(val))
249 */
250 
251 /* end LINEAR_VALUE_IS_FLOAT
252  */
253 
254 /*
255  #### # # ## ##### # #
256  # # # # # # # # # #
257  # ###### # # # # #######
258  # # # ###### ##### # #
259  # # # # # # # # # #
260  #### # # # # # #
261 
262  */
263 
264 /* the purpose of the chars version is to detect invalid assignments
265  */
266 #elif defined(LINEAR_VALUE_IS_CHARS)
267 #define LINEAR_VALUE_STRING "chars..."
268 typedef union { char *s; long l; int i; float f; double d;} Value;
269 #define VALUE_FMT "%s"
270 #define VALUE_CONST(val) ((Value)(val))
271 #define VALUE_NAN ((Value)(long)0xdadeebee)
272 #define VALUE_MIN ((Value)(long)0xdeadbeef)
273 #define VALUE_MAX ((Value)(long)0xfeedabee)
274 #define VALUE_ZERO ((Value)0)
275 #define VALUE_ONE ((Value)1)
276 #define VALUE_MONE ((Value)-1)
277 #define VALUE_TO_LONG(val) (val.l)
278 #define VALUE_TO_INT(val) (val.i)
279 #define VALUE_TO_FLOAT(val) (val.f)
280 #define VALUE_TO_DOUBLE(val) (val.d)
281 
282 /* end LINEAR_VALUE_IS_CHARS
283  */
284 
285 /*
286  # # # #####
287  # ## # #
288  # # # # #
289  # # # # #
290  # # ## #
291  # # # #
292 
293  */
294 #else /* default: LINEAR_VALUE_IS_INT */
295 #define LINEAR_VALUE_STRING "int"
296 typedef int Value;
297 #define VALUE_FMT "%d"
298 #define VALUE_CONST(val) (val)
299 #define VALUE_NAN INT_MIN
300 #define VALUE_MIN (INT_MIN+1)
301 #define VALUE_MAX INT_MAX
302 #define VALUE_ZERO 0
303 #define VALUE_ONE 1
304 #define VALUE_MONE -1
305 #define VALUE_TO_LONG(val) ((long)(val))
306 #define VALUE_TO_INT(val) ((int)(val))
307 #define VALUE_TO_FLOAT(val) ((float)(val))
308 #define VALUE_TO_DOUBLE(val) ((double)(val))
309 /* end LINEAR_VALUE_IS_INT
310  */
311 #endif
312 
313 /************************** ************ MACROS FOR MANIPULATING VALUES... */
314 
315 /* cast to value
316  */
317 #define int_to_value(i) ((Value)(i))
318 #define long_to_value(l) ((Value)(l))
319 #define float_to_value(f) ((Value)(f))
320 #define double_to_value(d) ((Value)(d))
321 
322 /* bool operators on values
323  */
324 #define value_eq(v1,v2) ((v1)==(v2))
325 #define value_ne(v1,v2) ((v1)!=(v2))
326 #define value_gt(v1,v2) ((v1)>(v2))
327 #define value_ge(v1,v2) ((v1)>=(v2))
328 #define value_lt(v1,v2) ((v1)<(v2))
329 #define value_le(v1,v2) ((v1)<=(v2))
330 
331 /* trian operators on values
332  */
333 #define value_sign(v) (value_eq(v,VALUE_ZERO)?0:value_lt(v,VALUE_ZERO)?-1:1)
334 #define value_compare(v1,v2) (value_eq(v1,v2)?0:value_lt(v1,v2)?-1:1)
335 
336 /* binary operators on values
337  *
338  * pdiv and pmod always return a positive remainder and a positive
339  * modulo. E.g. -1/100 = -1 and its remainder is 99. The modulo
340  * operator is periodic and not symmetric around zero.
341  */
342 #define value_plus(v1,v2) ((v1)+(v2))
343 #define value_div(v1,v2) ((v1)/(v2))
344 #define value_mod(v1,v2) ((v1)%(v2))
345 #define value_direct_multiply(v1,v2) ((v1)*(v2)) /* direct! */
346 #define value_minus(v1,v2) ((v1)-(v2))
347 #define value_pdiv(v1,v2) (divide(v1,v2))
348 #define value_pmod(v1,v2) (modulo(v1,v2))
349 #define value_min(v1,v2) (value_le(v1,v2)? (v1): (v2))
350 #define value_max(v1,v2) (value_ge(v1,v2)? (v1): (v2))
351 #define value_or(v1,v2) ((v1)|(v2))
352 #define value_and(v1,v2) ((v1)&(v2))
353 #define value_lshift(v1,v2) ((v1)<<(v2))
354 #define value_rshift(v1,v2) ((v1)>>(v2))
355 
356 /* assigments
357  */
358 #define value_assign(ref,val) (ref=(val))
359 #define value_addto(ref,val) (ref+=(val))
360 #define value_increment(ref) (ref++)
361 #define value_direct_product(ref,val) (ref*=(val)) /* direct! */
362 #define value_multiply(ref,val) value_assign(ref,value_mult(ref,val))
363 #define value_substract(ref,val) (ref-=(val))
364 #define value_decrement(ref) (ref--)
365 #define value_division(ref,val) (ref/=(val))
366 #define value_modulus(ref,val) (ref%=(val))
367 #define value_pdivision(ref,val) value_assign(ref,value_pdiv(ref,val))
368 #define value_oppose(ref) value_assign(ref,value_uminus(ref))
369 #define value_absolute(ref) value_assign(ref,value_abs(ref))
370 #define value_minimum(ref,val) value_assign(ref,value_min(ref,val))
371 #define value_maximum(ref,val) value_assign(ref,value_max(ref,val))
372 #define value_orto(ref,val) (ref |= (val))
373 #define value_andto(ref,val) (ref &= (val))
374 
375 /* unary operators on values
376  */
377 #define value_uminus(val) (-(val))
378 #define value_not(val) (~(val))
379 #define value_abs(val) \
380  ((value_posz_p(val) ? (val) : \
381  (value_ne((val), VALUE_NAN) ? value_uminus(val) : \
382  (THROW (overflow_error), VALUE_NAN ))))
383 
384 #define value_pos_p(val) value_gt(val,VALUE_ZERO)
385 #define value_neg_p(val) value_lt(val,VALUE_ZERO)
386 #define value_posz_p(val) value_ge(val,VALUE_ZERO)
387 #define value_negz_p(val) value_le(val,VALUE_ZERO)
388 #define value_zero_p(val) value_eq(val,VALUE_ZERO)
389 // No underscore between "not" and "zero": value_not_zero_p()
390 // Added to improve retrieval
391 #define value_notzero_p(val) value_ne(val,VALUE_ZERO)
392 #define value_one_p(val) value_eq(val,VALUE_ONE)
393 #define value_notone_p(val) value_ne(val,VALUE_ONE)
394 #define value_mone_p(val) value_eq(val,VALUE_MONE)
395 #define value_notmone_p(val) value_ne(val,VALUE_MONE)
396 #define value_min_p(val) value_eq(val,VALUE_MIN)
397 #define value_max_p(val) value_eq(val,VALUE_MAX)
398 #define value_notmin_p(val) value_ne(val,VALUE_MIN)
399 #define value_notmax_p(val) value_ne(val,VALUE_MAX)
400 
401 
402 /************************************************* PROTECTED MULTIPLICATION */
403 #include "arithmetic_errors.h"
404 
405 /* (|v| < MAX / |w|) => v*w is okay
406  * I could check ((v*w)/w)==v but a tmp would be useful
407  */
408 #define value_protected_hard_idiv_multiply(v,w,throw) \
409  ((value_zero_p(w) || value_zero_p(v))? VALUE_ZERO: \
410  value_lt(value_abs(v),value_div(VALUE_MAX,value_abs(w)))? \
411  value_direct_multiply(v,w): (throw, VALUE_NAN))
412 
413 /* is a software idiv is assumed, quick check performed first
414  */
415 #if defined(LINEAR_VALUE_ASSUME_SOFTWARE_IDIV)
416 #define value_protected_multiply(v,w,throw) \
417  ((value_le(v,VALUE_SQRT_MAX) && value_le(w,VALUE_SQRT_MAX) && \
418  value_ge(v,VALUE_SQRT_MIN) && value_ge(w,VALUE_SQRT_MIN))? \
419  value_direct_multiply(v,w): value_protected_hard_idiv_multiply(v,w,throw))
420 #else
421 #define value_protected_multiply(v,w,throw) \
422  value_protected_hard_idiv_multiply(v,w,throw)
423 #endif
424 
425 /* protected versions
426  */
427 #define value_protected_mult(v,w) \
428  value_protected_multiply(v,w,THROW(overflow_error))
429 #define value_protected_product(v,w) \
430  v=value_protected_mult(v,w)
431 
432 /* whether the default is protected or not
433  * this define makes no sense any more... well, doesn't matter. FC.
434  */
435 #if defined(LINEAR_VALUE_PROTECT_MULTIPLY)
436 #define value_mult(v,w) value_protected_mult(v,w)
437 #define value_product(v,w) value_protected_product(v,w)
438 #else
439 
440 /* I do enforce the protection whatever requested:-)
441  * prints out a message and throws the exception, hoping
442  * that some valid CATCH waits for it upwards.
443  */
444 #define value_mult(v,w) \
445  value_protected_multiply(v,w, \
446  (fprintf(stderr,"[value_mult] value overflow!\n"),THROW(overflow_error)))
447 #define value_product(v,w) v=value_mult(v,w)
448 
449 /* was:
450  * #define value_mult(v,w) value_direct_multiply(v,w)
451  * #define value_product(v,w) value_direct_product(v,w)
452  * could be: protected versions...
453  */
454 #endif
455 
456 /******************************************************* STATIC VALUE DEBUG */
457 
458 /* LINEAR_VALUE_IS_CHARS is used for type checking.
459  * some operations are not allowed on (char*), thus
460  * they are switched to some other operation here...
461  */
462 #if defined(LINEAR_VALUE_IS_CHARS)
463 #define value_fake_binary(v1,v2) ((Value)((v1).i+(v2).i))
464 #define value_bool_binary(v1,v2) ((int)((v1).i+(v2).i))
465 #undef float_to_value
466 #define float_to_value(f) ((Value)f)
467 #undef double_to_value
468 #define double_to_value(f) ((Value)f)
469 #undef value_uminus
470 #define value_uminus(v) (v)
471 #undef value_mult
472 #define value_mult(v1,v2) value_fake_binary(v1,v2)
473 #undef value_mod
474 #define value_mod(v1,v2) value_fake_binary(v1,v2)
475 #undef value_ge
476 #define value_ge(v1,v2) value_bool_binary(v1,v2)
477 #undef value_gt
478 #define value_gt(v1,v2) value_bool_binary(v1,v2)
479 #undef value_le
480 #define value_le(v1,v2) value_bool_binary(v1,v2)
481 #undef value_lt
482 #define value_lt(v1,v2) value_bool_binary(v1,v2)
483 #undef value_ne
484 #define value_ne(v1,v2) value_bool_binary(v1,v2)
485 #undef value_eq
486 #define value_eq(v1,v2) value_bool_binary(v1,v2)
487 #undef value_plus
488 #define value_plus(v1,v2) value_fake_binary(v1,v2)
489 #undef value_minus
490 #define value_minus(v1,v2) value_fake_binary(v1,v2)
491 #undef value_pdiv
492 #define value_pdiv(v1,v2) value_fake_binary(v1,v2)
493 #undef value_div
494 #define value_div(v1,v2) value_fake_binary(v1,v2)
495 #undef value_mod
496 #define value_mod(v1,v2) value_fake_binary(v1,v2)
497 #undef value_addto
498 #define value_addto(v1,v2) value_assign(v1,value_plus(v1,v2))
499 #undef value_substract
500 #define value_substract(v1,v2) value_addto(v1,v2)
501 #undef value_product
502 #define value_product(v1,v2) value_addto(v1,v2)
503 #undef value_modulus
504 #define value_modulus(v1,v2) value_addto(v1,v2)
505 #undef value_division
506 #define value_division(v1,v2) value_addto(v1,v2)
507 #undef value_increment
508 #define value_increment(v) value_addto(v,VALUE_ONE)
509 #undef value_decrement
510 #define value_decrement(v) value_addto(v,VALUE_MONE)
511 #undef value_orto
512 #define value_orto(ref,val) value_addto(v1,v2)
513 #undef value_andto
514 #define value_andto(ref,val) value_addto(v1,v2)
515 #undef value_or
516 #define value_or(v1,v2) value_fake_binary(v1,v2)
517 #undef value_and
518 #define value_and(v1,v2) value_fake_binary(v1,v2)
519 #undef value_lshift
520 #define value_lshift(v1,v2) value_fake_binary(v1,v2)
521 #undef value_rshift
522 #define value_rshift(v1,v2) value_fake_binary(v1,v2)
523 #endif
524 
525 
526 /* valeur absolue
527  */
528 #ifndef ABS
529 #define ABS(x) (((x)>=0) ? (x) : -(x))
530 #endif
531 
532 /* minimum and maximum
533  * if they are defined somewhere else, they are very likely
534  * to be defined the same way. Thus the previous def is not overwritten.
535  */
536 #ifndef MIN
537 #define MIN(x,y) (((x)>=(y))?(y):(x))
538 #endif
539 #ifndef MAX
540 #define MAX(x,y) (((x)>=(y))?(x):(y))
541 #endif
542 
543 /* signe d'un entier: -1, 0 ou 1 */
544 #define SIGN(x) (((x)>0)? 1 : ((x)==0? 0 : -1))
545 
546 /* division avec reste toujours positif
547  * basee sur les equations:
548  * a/(-b) = - (a/b)
549  * (-a)/b = - ((a+b-1)/b)
550  * ou a et b sont des entiers positifs
551  */
552 #define DIVIDE(x,y) ((y)>0? POSITIVE_DIVIDE(x,y) : \
553  -POSITIVE_DIVIDE((x),(-(y))))
554 
555 /* division avec reste toujours positif quand y est positif: assert(y>=0) */
556 #define POSITIVE_DIVIDE(x,y) ((x)>0 ? (x)/(y) : - (-(x)+(y)-1)/(y))
557 
558 /* modulo a resultat toujours positif */
559 #define MODULO(x,y) ((y)>0 ? POSITIVE_MODULO(x,y) : POSITIVE_MODULO(-x,-y))
560 
561 /* modulo par rapport a un nombre positif: assert(y>=0)
562  *
563  * Ce n'est pas la macro la plus efficace que j'aie jamais ecrite: il faut
564  * faire, dans le pire des cas, deux appels a la routine .rem, qui n'est
565  * surement pas plus cablee que la division ou la multiplication
566  */
567 #define POSITIVE_MODULO(x,y) ((x) > 0 ? (x)%(y) : \
568  ((x)%(y) == 0 ? 0 : ((y)-(-(x))%(y))))
569 
570 /* Pour la recherche de performance, selection d'une implementation
571  * particuliere des fonctions
572  */
573 
574 #define pgcd(a,b) pgcd_slow(a,b)
575 
576 #define divide(a,b) DIVIDE(a,b)
577 
578 #define modulo(a,b) MODULO(a,b)
579 
580 typedef struct { Value num, den; int numero ; } frac ;
581 typedef struct col{ int taille, existe ; frac *colonne ;} tableau ;
582 
583 // manual declaration, as cproto seems to ignore attributes
584 extern void __attribute__ ((weak, noreturn))
585 throw_exception(const int, const char *, const char *, const int);
586 
587 // for some yacc-generated code
588 #ifndef _has_yy_size_t
589 #define _has_yy_size_t
590 typedef size_t yy_size_t;
591 #endif /* _has_yy_size_t */
592 
593 /* end of arithmetique-local.h */
void __attribute__((weak, noreturn)) throw_exception(const int
int Value
size_t yy_size_t
struct col tableau
void throw_exception(const int, const char *, const char *, const int)
static int num
Definition: bourdoncle.c:137
int f(int off1, int off2, int n, float r[n], float a[n], float b[n])
Definition: offsets.c:15
frac * colonne