00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef arithmetique_header_included
00020 #define arithmetique_header_included
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048 #include <stdio.h>
00049 #include <limits.h>
00050
00051 #ifdef GNUMP
00052 #include <gmp.h>
00053 #include <stdlib.h>
00054 #include <string.h>
00055 #ifndef mp_get_memory_functions
00056 #if defined(__cplusplus)
00057 extern "C" {
00058 #endif
00059 void mp_get_memory_functions(
00060 void *(**alloc_func_ptr) (size_t),
00061 void *(**realloc_func_ptr) (void *, size_t, size_t),
00062 void (**free_func_ptr) (void *, size_t));
00063 #if defined(__cplusplus)
00064 }
00065 #endif
00066 #endif
00067 #endif
00068
00069 #ifdef CLN
00070 #include <sstream>
00071 #define WANT_OBFUSCATING_OPERATORS
00072 #include <cln/cln.h>
00073 #endif
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090 #ifndef LONG_LONG_MAX
00091
00092
00093
00094
00095
00096
00097 #ifndef __LONG_LONG_MAX__
00098 #define __LONG_LONG_MAX__ 9223372036854775807LL
00099 #endif
00100 #undef LONG_LONG_MAX
00101 #define LONG_LONG_MAX __LONG_LONG_MAX__
00102 #undef LONG_LONG_MIN
00103 #define LONG_LONG_MIN (-LONG_LONG_MAX-1)
00104 #undef ULONG_LONG_MAX
00105 #define ULONG_LONG_MAX (LONG_LONG_MAX * 2ULL + 1)
00106 #endif
00107
00108 #if defined(LINEAR_VALUE_IS_LONGLONG)
00109
00110 #define LINEAR_VALUE_STRING "long long int"
00111 typedef long long int Value;
00112 #if defined(WIN32) && !defined(unix)
00113
00114 # define VALUE_FMT "%I64d"
00115 #else
00116 # define VALUE_FMT "%lld"
00117 #endif
00118 #define VALUE_CONST(val) (val##LL)
00119
00120
00121
00122
00123
00124
00125 #define VALUE_NAN LONG_LONG_MIN
00126 #define VALUE_MIN (LONG_LONG_MIN+1LL)
00127 #define VALUE_MAX LONG_LONG_MAX
00128 #define VALUE_SQRT_MIN long_to_value(LONG_MIN)
00129 #define VALUE_SQRT_MAX long_to_value(LONG_MAX)
00130 #define VALUE_ZERO (0LL)
00131 #define VALUE_ONE (1LL)
00132 #define VALUE_MONE (-1LL)
00133
00134 #define VALUE_TO_LONG(val) \
00135 ((long)((val)>(Value)LONG_MIN&&(val)<=(Value)LONG_MAX)?\
00136 (val):(THROW(overflow_error), LONG_MIN))
00137
00138 #define VALUE_TO_INT(val) \
00139 ((int)((val)>(Value)INT_MIN&&(val)<=(Value)INT_MAX)?\
00140 (val):(THROW(overflow_error), INT_MIN))
00141
00142 #define VALUE_TO_DOUBLE(val) ((double)(val))
00143
00144
00145 #define VALUE_TO_FLOAT(val) ((float)((int)(val)))
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160 #elif defined(LINEAR_VALUE_IS_LONG)
00161
00162 #define LINEAR_VALUE_STRING "long int"
00163 typedef long Value;
00164 #define VALUE_FMT "%ld"
00165 #define VALUE_CONST(val) (val##L)
00166 #define VALUE_NAN LONG_MIN
00167 #define VALUE_MIN (LONG_MIN+1L)
00168 #define VALUE_MAX LONG_MAX
00169 #define VALUE_SQRT_MIN int_to_value(INT_MIN)
00170 #define VALUE_SQRT_MAX int_to_value(INT_MAX)
00171 #define VALUE_ZERO 0L
00172 #define VALUE_ONE 1L
00173 #define VALUE_MONE -1L
00174 #define VALUE_TO_LONG(val) (val)
00175 #define VALUE_TO_INT(val) ((int)(val))
00176 #define VALUE_TO_FLOAT(val) ((float)(val))
00177 #define VALUE_TO_DOUBLE(val) ((double)(val))
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224 #elif defined(LINEAR_VALUE_IS_CHARS)
00225
00226 #define LINEAR_VALUE_STRING "char"
00227 typedef union { char *s; long l; int i; float f; double d;} Value;
00228 #define VALUE_FMT "%s"
00229 #define VALUE_CONST(val) ((Value)(val))
00230 #define VALUE_NAN ((Value)(long)0xdadeebee)
00231 #define VALUE_MIN ((Value)(long)0xdeadbeef)
00232 #define VALUE_MAX ((Value)(long)0xfeedabee)
00233 #define VALUE_ZERO ((Value)0)
00234 #define VALUE_ONE ((Value)1)
00235 #define VALUE_MONE ((Value)-1)
00236 #define VALUE_TO_LONG(val) (val.l)
00237 #define VALUE_TO_INT(val) (val.i)
00238 #define VALUE_TO_FLOAT(val) (val.f)
00239 #define VALUE_TO_DOUBLE(val) (val.d)
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253 #elif defined(LINEAR_VALUE_IS_INT)
00254
00255 #define LINEAR_VALUE_STRING "int"
00256 typedef int Value;
00257 #define VALUE_FMT "%d"
00258 #define VALUE_CONST(val) (val)
00259 #define VALUE_NAN INT_MIN
00260 #define VALUE_MIN (INT_MIN+1)
00261 #define VALUE_MAX INT_MAX
00262 #define VALUE_ZERO 0
00263 #define VALUE_ONE 1
00264 #define VALUE_MONE -1
00265 #define VALUE_TO_LONG(val) ((long)(val))
00266 #define VALUE_TO_INT(val) ((int)(val))
00267 #define VALUE_TO_FLOAT(val) ((float)(val))
00268 #define VALUE_TO_DOUBLE(val) ((double)(val))
00269
00270
00271
00272 #elif defined(GNUMP)
00273
00274 #define LINEAR_VALUE_STRING "gmp"
00275 typedef mpz_t Value;
00276 #define VALUE_FMT "%s"
00277
00278
00279 #undef VALUE_ZERO
00280 #undef VALUE_ONE
00281 #undef VALUE_MONE
00282 #define VALUE_TO_LONG(val) (mpz_get_si(val))
00283 #define VALUE_TO_INT(val) ((int)mpz_get_si(val))
00284 #define VALUE_TO_FLOAT(val) ((float)((int)mpz_get_si(val)))
00285 #define VALUE_TO_DOUBLE(val) (mpz_get_d(val))
00286
00287 #elif defined(CLN)
00288
00289 #define LINEAR_VALUE_STRING "cln"
00290 typedef cln::cl_I Value;
00291 #define VALUE_FMT "%s"
00292
00293 #define VALUE_TO_INT(val) (cln::cl_I_to_int(val))
00294 #define VALUE_TO_DOUBLE(val) (cln::double_approx(val))
00295
00296 #endif
00297
00298
00299
00300 #if defined(CLN)
00301
00302 #define value_init(val) ((val).word = ((cln::cl_uint)cl_FN_tag) << cl_tag_shift)
00303 #define value_assign(v1,v2) ((v1) = (v2))
00304 #define value_set_si(val,i) ((val) = (i))
00305 #define value_set_double(val,d) ((val) = cln::truncate1(cln::cl_R(d)))
00306 #define value_clear(val) ((val) = 0)
00307 #define value_read(val,str) ((val) = (str))
00308 #define value_print(Dst,fmt,val) {std::ostringstream strm; strm << val; \
00309 fprintf((Dst),(fmt),strm.str().c_str()); \
00310 }
00311 #define value_swap(v1,v2) {Value tmp; tmp = v2; \
00312 v2 = v1; v1 = tmp; \
00313 }
00314
00315
00316
00317 #define value_eq(v1,v2) ((v1)==(v2))
00318 #define value_ne(v1,v2) ((v1)!=(v2))
00319 #define value_gt(v1,v2) ((v1)>(v2))
00320 #define value_ge(v1,v2) ((v1)>=(v2))
00321 #define value_lt(v1,v2) ((v1)<(v2))
00322 #define value_le(v1,v2) ((v1)<=(v2))
00323
00324 #define value_abs_eq(v1,v2) (cln::abs(v1)==cln::abs(v2))
00325 #define value_abs_ne(v1,v2) (cln::abs(v1)!=cln::abs(v2))
00326 #define value_abs_gt(v1,v2) (cln::abs(v1)>cln::abs(v2))
00327 #define value_abs_ge(v1,v2) (cln::abs(v1)>=cln::abs(v2))
00328 #define value_abs_lt(v1,v2) (cln::abs(v1)<cln::abs(v2))
00329 #define value_abs_le(v1,v2) (cln::abs(v1)<=cln::abs(v2))
00330
00331 #define value_sign(val) (cln::signum(val))
00332 #define value_compare(v1,v2) (cln::compare((v1),(v2)))
00333
00334 #define value_addto(ref,val1,val2) ((ref) = (val1)+(val2))
00335 #define value_add_int(ref,val,vint) ((ref) = (val)+(vint))
00336 #define value_addmul(ref, val1, val2) ((ref) += (val1)*(val2))
00337 #define value_increment(ref,val) ((ref) = (val)+1)
00338 #define value_multiply(ref,val1,val2) ((ref) = (val1)*(val2))
00339 #define value_subtract(ref,val1,val2) ((ref) = (val1)-(val2))
00340 #define value_sub_int(ref,val1,val2) ((ref) = (val1)-(val2))
00341 #define value_decrement(ref,val) ((ref) = (val)-1)
00342 #define value_division(ref,val1,val2) ((ref) = cln::truncate1(val1,val2))
00343 #define value_divexact(ref,val1,val2) ((ref) = cln::exquo(val1,val2))
00344 #define value_modulus(ref,val1,val2) ((ref) = cln::truncate2(val1,val2).remainder)
00345 #define value_pdivision(ref,val1,val2) ((ref) = cln::floor1(val1,val2))
00346 #define value_pmodulus(ref,val1,val2) ((ref) = cln::floor2(val1,val2).remainder)
00347 #define value_oppose(ref,val) ((ref) = -(val))
00348 #define value_absolute(ref,val) ((ref) = cln::abs(val))
00349 #define value_minimum(ref,val1,val2) ((ref) = cln::min((val1),(val2)))
00350 #define value_maximum(ref,val1,val2) ((ref) = cln::max((val1),(val2)))
00351 #define value_gcd(ref,val1,val2) ((ref) = cln::gcd((val1),(val2)))
00352 #define value_lcm(ref,val1,val2) ((ref) = cln::lcm((val1),(val2)))
00353 #define value_orto(ref,val1,val2) ((ref) = (val1)|(val2))
00354 #define value_andto(ref,val1,val2) ((ref) = (val1)&(val2))
00355
00356
00357
00358 #define value_pos_p(val) ((val) > 0)
00359 #define value_neg_p(val) ((val) < 0)
00360 #define value_posz_p(val) ((val) >= 0)
00361 #define value_negz_p(val) ((val) <= 0)
00362 #define value_zero_p(val) ((val) == 0)
00363 #define value_notzero_p(val) ((val) != 0)
00364 #define value_one_p(val) ((val) == 1)
00365 #define value_notone_p(val) ((val) != 1)
00366 #define value_mone_p(val) ((val) == -1)
00367 #define value_notmone_p(val) ((val) != -1)
00368 #define value_cmp_si(val, n) (cln::compare(val,n))
00369
00370 #elif defined(GNUMP)
00371
00372
00373
00374 #define value_init(val) (mpz_init((val)))
00375 #define value_assign(v1,v2) (mpz_set((v1),(v2)))
00376 #define value_set_si(val,i) (mpz_set_si((val),(i)))
00377 #define value_set_double(val,d)(mpz_set_d((val),(d)))
00378 #define value_clear(val) (mpz_clear((val)))
00379 #define value_read(val,str) (mpz_set_str((val),(str),10))
00380 typedef void (*value_print_gmp_free_t)(void *, size_t);
00381 #define value_print(Dst,fmt,val) {char *str; \
00382 value_print_gmp_free_t gmp_free; \
00383 str = mpz_get_str(0,10,(val)); \
00384 fprintf((Dst),(fmt),str); \
00385 mp_get_memory_functions(NULL, NULL, &gmp_free); \
00386 (*gmp_free) (str, strlen(str)+1); \
00387 }
00388 #define value_swap(val1,val2) (mpz_swap(val1, val2))
00389
00390
00391
00392 #define value_eq(v1,v2) (mpz_cmp((v1),(v2)) == 0)
00393 #define value_ne(v1,v2) (mpz_cmp((v1),(v2)) != 0)
00394 #define value_gt(v1,v2) (mpz_cmp((v1),(v2)) > 0)
00395 #define value_ge(v1,v2) (mpz_cmp((v1),(v2)) >= 0)
00396 #define value_lt(v1,v2) (mpz_cmp((v1),(v2)) < 0)
00397 #define value_le(v1,v2) (mpz_cmp((v1),(v2)) <= 0)
00398
00399 #define value_abs_eq(v1,v2) (mpz_cmpabs((v1),(v2)) == 0)
00400 #define value_abs_ne(v1,v2) (mpz_cmpabs((v1),(v2)) != 0)
00401 #define value_abs_gt(v1,v2) (mpz_cmpabs((v1),(v2)) > 0)
00402 #define value_abs_ge(v1,v2) (mpz_cmpabs((v1),(v2)) >= 0)
00403 #define value_abs_lt(v1,v2) (mpz_cmpabs((v1),(v2)) < 0)
00404 #define value_abs_le(v1,v2) (mpz_cmpabs((v1),(v2)) <= 0)
00405
00406
00407
00408 #define value_sign(val) (mpz_sgn(val))
00409 #define value_compare(v1,v2) (mpz_cmp((v1),(v2)))
00410
00411
00412
00413 #define value_addto(ref,val1,val2) (mpz_add((ref),(val1),(val2)))
00414 #define value_add_int(ref,val,vint) (mpz_add_ui((ref),(val),(long)(vint)))
00415 #define value_addmul(ref, val1, val2) (mpz_addmul((ref), (val1), (val2)))
00416 #define value_increment(ref,val) (mpz_add_ui((ref),(val),1))
00417 #define value_multiply(ref,val1,val2) (mpz_mul((ref),(val1),(val2)))
00418 #define value_subtract(ref,val1,val2) (mpz_sub((ref),(val1),(val2)))
00419 #define value_sub_int(ref,val,vint) (mpz_sub_ui((ref),(val),(long)(vint)))
00420 #define value_decrement(ref,val) (mpz_sub_ui((ref),(val),1))
00421 #define value_division(ref,val1,val2) (mpz_tdiv_q((ref),(val1),(val2)))
00422 #define value_divexact(ref,val1,val2) (mpz_divexact((ref),(val1),(val2)))
00423 #define value_modulus(ref,val1,val2) (mpz_tdiv_r((ref),(val1),(val2)))
00424 #define value_pdivision(ref,val1,val2) (mpz_fdiv_q((ref),(val1),(val2)))
00425 #define value_pmodulus(ref,val1,val2) (mpz_fdiv_r((ref),(val1),(val2)))
00426 #define value_oppose(ref,val) (mpz_neg((ref),(val)))
00427 #define value_absolute(ref,val) (mpz_abs((ref),(val)))
00428 #define value_minimum(ref,val1,val2) (value_le((val1),(val2)) ? \
00429 mpz_set((ref),(val1)) : \
00430 mpz_set((ref),(val2)))
00431 #define value_maximum(ref,val1,val2) (value_ge((val1),(val2)) ? \
00432 mpz_set((ref),(val1)) : \
00433 mpz_set((ref),(val2)))
00434 #define value_gcd(ref,val1,val2) (mpz_gcd(ref,val1,val2))
00435 #define value_lcm(ref,val1,val2) (mpz_lcm(ref,val1,val2))
00436 #define value_orto(ref,val1,val2) (mpz_ior((ref),(val1),(val2)))
00437 #define value_andto(ref,val1,val2) (mpz_and((ref),(val1),(val2)))
00438
00439
00440
00441 #define value_pos_p(val) (mpz_sgn(val) > 0)
00442 #define value_neg_p(val) (mpz_sgn(val) < 0)
00443 #define value_posz_p(val) (mpz_sgn(val) >= 0)
00444 #define value_negz_p(val) (mpz_sgn(val) <= 0)
00445 #define value_zero_p(val) (mpz_sgn(val) == 0)
00446 #define value_notzero_p(val) (mpz_sgn(val) != 0)
00447 #define value_one_p(val) (mpz_cmp_si(val,1) == 0)
00448 #define value_notone_p(val) (mpz_cmp_si(val,1) != 0)
00449 #define value_mone_p(val) (mpz_cmp_si(val,-1) ==0)
00450 #define value_notmone_p(val) (mpz_cmp_si(val,-1) !=0)
00451 #define value_cmp_si(val, n) (mpz_cmp_si(val,n))
00452
00453
00454
00455 #else
00456
00457
00458 #define value_init(val) ((val) = 0)
00459 #define value_assign(v1,v2) ((v1) = (v2))
00460 #define value_set_si(val,i) ((val) = (Value)(i))
00461 #define value_set_double(val,d) ((val) = (Value)(d))
00462 #define value_clear(val) ((val) = 0)
00463 #define value_read(val,str) (sscanf((str),VALUE_FMT,&(val)))
00464 #define value_print(Dst,fmt,val) (fprintf((Dst),(fmt),(val)))
00465 #define value_swap(v1,v2) {Value tmp; tmp = v2; \
00466 v2 = v1; v1 = tmp; \
00467 }
00468
00469
00470 #define int_to_value(i) ((Value)(i))
00471 #define long_to_value(l) ((Value)(l))
00472 #define float_to_value(f) ((Value)(f))
00473 #define double_to_value(d) ((Value)(d))
00474
00475
00476
00477 #define value_eq(v1,v2) ((v1)==(v2))
00478 #define value_ne(v1,v2) ((v1)!=(v2))
00479 #define value_gt(v1,v2) ((v1)>(v2))
00480 #define value_ge(v1,v2) ((v1)>=(v2))
00481 #define value_lt(v1,v2) ((v1)<(v2))
00482 #define value_le(v1,v2) ((v1)<=(v2))
00483
00484 #define value_abs_eq(v1,v2) (value_abs(v1)==value_abs(v2))
00485 #define value_abs_ne(v1,v2) (value_abs(v1)!=value_abs(v2))
00486 #define value_abs_gt(v1,v2) (value_abs(v1)>value_abs(v2))
00487 #define value_abs_ge(v1,v2) (value_abs(v1)>=value_abs(v2))
00488 #define value_abs_lt(v1,v2) (value_abs(v1)<value_abs(v2))
00489 #define value_abs_le(v1,v2) (value_abs(v1)<=value_abs(v2))
00490
00491
00492
00493 #define value_sign(v) (value_eq(v,VALUE_ZERO)?0:value_lt(v,VALUE_ZERO)?-1:1)
00494 #define value_compare(v1,v2) (value_eq(v1,v2)?0:value_lt(v1,v2)?-1:1)
00495
00496
00497
00498 #define value_plus(v1,v2) ((v1)+(v2))
00499 #define value_div(v1,v2) ((v1)/(v2))
00500 #define value_mod(v1,v2) ((v1)%(v2))
00501 #define value_direct_multiply(v1,v2) ((v1)*(v2))
00502 #define value_minus(v1,v2) ((v1)-(v2))
00503 #define value_pdiv(v1,v2) (DIVIDE((v1),(v2)))
00504 #define value_pmod(v1,v2) (MODULO((v1),(v2)))
00505 #define value_min(v1,v2) (value_le((v1),(v2))? (v1): (v2))
00506 #define value_max(v1,v2) (value_ge((v1),(v2))? (v1): (v2))
00507 #define value_or(v1,v2) ((v1)|(v2))
00508 #define value_and(v1,v2) ((v1)&(v2))
00509 #define value_lshift(v1,v2) ((v1)<<(v2))
00510 #define value_rshift(v1,v2) ((v1)>>(v2))
00511
00512
00513
00514 #define value_addto(ref,val1,val2) ((ref) = (val1)+(val2))
00515 #define value_add_int(ref,val,vint) ((ref) = (val)+(Value)(vint))
00516 #define value_addmul(ref, val1, val2) ((ref) += (val1)*(val2))
00517 #define value_increment(ref,val) ((ref) = (val)+VALUE_ONE)
00518 #define value_direct_product(ref,val1,val2) ((ref) = (val1)*(val2))
00519 #define value_multiply(ref,val1,val2) ((ref) = value_mult((val1),(val2)))
00520 #define value_subtract(ref,val1,val2) ((ref) = (val1)-(val2))
00521 #define value_sub_int(ref,val,vint) ((ref) = (val)-(Value)(vint))
00522 #define value_decrement(ref,val) ((ref) = (val)-VALUE_ONE)
00523 #define value_division(ref,val1,val2) ((ref) = (val1)/(val2))
00524 #define value_divexact(ref,val1,val2) ((ref) = (val1)/(val2))
00525 #define value_modulus(ref,val1,val2) ((ref) = (val1)%(val2))
00526 #define value_pdivision(ref,val1,val2) ((ref) = value_pdiv((val1),(val2)))
00527 #define value_pmodulus(ref,val1,val2) ((ref) = value_pmod((val1),(val2)))
00528 #define value_oppose(ref,val) ((ref) = value_uminus((val)))
00529 #define value_absolute(ref,val) ((ref) = value_abs((val)))
00530 #define value_minimum(ref,val1,val2) ((ref) = value_min((val1),(val2)))
00531 #define value_maximum(ref,val1,val2) ((ref) = value_max((val1),(val2)))
00532 #define value_gcd(ref,val1,val2) Gcd((val1),(val2),&(ref))
00533 #define value_lcm(ref,val1,val2) Lcm3((val1),(val2),&(ref))
00534 #define value_orto(ref,val1,val2) ((ref) = (val1)|(val2))
00535 #define value_andto(ref,val1,val2) ((ref) = (val1)&(val2))
00536
00537
00538
00539 #define value_uminus(val) (-(val))
00540 #define value_not(val) (~(val))
00541 #define value_abs(val) (value_posz_p(val)? \
00542 (val) : \
00543 (value_ne((val), VALUE_NAN) ? \
00544 value_uminus(val) : \
00545 (THROW (overflow_error), VALUE_NAN )))
00546
00547
00548
00549 #define value_pos_p(val) value_gt(val,VALUE_ZERO)
00550 #define value_neg_p(val) value_lt(val,VALUE_ZERO)
00551 #define value_posz_p(val) value_ge(val,VALUE_ZERO)
00552 #define value_negz_p(val) value_le(val,VALUE_ZERO)
00553 #define value_zero_p(val) value_eq(val,VALUE_ZERO)
00554 #define value_notzero_p(val) value_ne(val,VALUE_ZERO)
00555 #define value_one_p(val) value_eq(val,VALUE_ONE)
00556 #define value_notone_p(val) value_ne(val,VALUE_ONE)
00557 #define value_mone_p(val) value_eq(val,VALUE_MONE)
00558 #define value_notmone_p(val) value_ne(val,VALUE_MONE)
00559 #define value_cmp_si(val, n) (val - (n))
00560 #define value_min_p(val) value_eq(val,VALUE_MIN)
00561 #define value_max_p(val) value_eq(val,VALUE_MAX)
00562 #define value_notmin_p(val) value_ne(val,VALUE_MIN)
00563 #define value_notmax_p(val) value_ne(val,VALUE_MAX)
00564
00565 #endif
00566
00567
00568
00569
00570 #include "arithmetic_errors.h"
00571
00572
00573
00574
00575 #define value_protected_hard_idiv_multiply(v,w,throw) \
00576 ((value_zero_p(w) || value_zero_p(v))? VALUE_ZERO: \
00577 value_lt(value_abs(v),value_div(VALUE_MAX,value_abs(w)))? \
00578 value_direct_multiply(v,w): (throw, VALUE_NAN))
00579
00580
00581
00582 #if defined(LINEAR_VALUE_ASSUME_SOFTWARE_IDIV)
00583 #define value_protected_multiply(v,w,throw) \
00584 ((value_le(v,VALUE_SQRT_MAX) && value_le(w,VALUE_SQRT_MAX) && \
00585 value_ge(v,VALUE_SQRT_MIN) && value_ge(w,VALUE_SQRT_MIN))? \
00586 value_direct_multiply(v,w): value_protected_hard_idiv_multiply(v,w,throw))
00587 #else
00588 #define value_protected_multiply(v,w,throw) \
00589 value_protected_hard_idiv_multiply(v,w,throw)
00590 #endif
00591
00592
00593
00594 #define value_protected_mult(v,w) \
00595 value_protected_multiply(v,w,THROW(overflow_error))
00596 #define value_protected_product(v,w) \
00597 v=value_protected_mult(v,w)
00598
00599
00600
00601
00602 #if defined(LINEAR_VALUE_PROTECT_MULTIPLY)
00603 #define value_mult(v,w) value_protected_mult(v,w)
00604 #define value_product(v,w) value_protected_product(v,w)
00605 #else
00606
00607
00608
00609
00610
00611 #define value_mult(v,w) \
00612 value_protected_multiply(v,w, \
00613 (fprintf(stderr,"[value_mult] value overflow!\n"),THROW(overflow_error)))
00614 #define value_product(v,w) v=value_mult(v,w)
00615
00616
00617
00618
00619
00620
00621 #endif
00622
00623
00624
00625
00626
00627
00628
00629 #if defined(LINEAR_VALUE_IS_CHARS)
00630 #define value_fake_binary(v1,v2) ((Value)((v1).i+(v2).i))
00631 #define value_bool_binary(v1,v2) ((int)((v1).i+(v2).i))
00632 #undef float_to_value
00633 #define float_to_value(f) ((Value)f)
00634 #undef double_to_value
00635 #define double_to_value(f) ((Value)f)
00636 #undef value_uminus
00637 #define value_uminus(v) (v)
00638 #undef value_mult
00639 #define value_mult(v1,v2) value_fake_binary(v1,v2)
00640 #undef value_mod
00641 #define value_mod(v1,v2) value_fake_binary(v1,v2)
00642 #undef value_ge
00643 #define value_ge(v1,v2) value_bool_binary(v1,v2)
00644 #undef value_gt
00645 #define value_gt(v1,v2) value_bool_binary(v1,v2)
00646 #undef value_le
00647 #define value_le(v1,v2) value_bool_binary(v1,v2)
00648 #undef value_lt
00649 #define value_lt(v1,v2) value_bool_binary(v1,v2)
00650 #undef value_ne
00651 #define value_ne(v1,v2) value_bool_binary(v1,v2)
00652 #undef value_eq
00653 #define value_eq(v1,v2) value_bool_binary(v1,v2)
00654 #undef value_plus
00655 #define value_plus(v1,v2) value_fake_binary(v1,v2)
00656 #undef value_minus
00657 #define value_minus(v1,v2) value_fake_binary(v1,v2)
00658 #undef value_pdiv
00659 #define value_pdiv(v1,v2) value_fake_binary(v1,v2)
00660 #undef value_div
00661 #define value_div(v1,v2) value_fake_binary(v1,v2)
00662 #undef value_mod
00663 #define value_mod(v1,v2) value_fake_binary(v1,v2)
00664 #undef value_addto
00665 #define value_addto(v1,v2) value_assign(v1,value_plus(v1,v2))
00666 #undef value_subtract
00667 #define value_subtract(v1,v2) value_addto(v1,v2)
00668 #undef value_product
00669 #define value_product(v1,v2) value_addto(v1,v2)
00670 #undef value_modulus
00671 #define value_modulus(v1,v2) value_addto(v1,v2)
00672 #undef value_division
00673 #define value_division(v1,v2) value_addto(v1,v2)
00674 #undef value_divexact
00675 #define value_divexact(v1,v2) value_addto(v1,v2)
00676 #undef value_increment
00677 #define value_increment(v) value_addto(v,VALUE_ONE)
00678 #undef value_decrement
00679 #define value_decrement(v) value_addto(v,VALUE_MONE)
00680 #undef value_orto
00681 #define value_orto(ref,val) value_addto(v1,v2)
00682 #undef value_andto
00683 #define value_andto(ref,val) value_addto(v1,v2)
00684 #undef value_or
00685 #define value_or(v1,v2) value_fake_binary(v1,v2)
00686 #undef value_and
00687 #define value_and(v1,v2) value_fake_binary(v1,v2)
00688 #undef value_lshift
00689 #define value_lshift(v1,v2) value_fake_binary(v1,v2)
00690 #undef value_rshift
00691 #define value_rshift(v1,v2) value_fake_binary(v1,v2)
00692 #endif
00693
00694
00695 #define value_substract(ref,val1,val2) (value_subtract((ref),(val1),(val2)))
00696
00697
00698
00699 #ifndef ABS
00700 #define ABS(x) (((x)>=0) ? (x) : -(x))
00701 #endif
00702
00703
00704
00705
00706
00707 #ifndef MIN
00708 #define MIN(x,y) (((x)>=(y))?(y):(x))
00709 #endif
00710 #ifndef MAX
00711 #define MAX(x,y) (((x)>=(y))?(x):(y))
00712 #endif
00713
00714
00715 #define SIGN(x) (((x)>0)? 1 : ((x)==0? 0 : -1))
00716
00717
00718
00719
00720
00721
00722
00723 #define DIVIDE(x,y) ((y)>0? POSITIVE_DIVIDE(x,y) : \
00724 -POSITIVE_DIVIDE((x),(-(y))))
00725
00726
00727 #define POSITIVE_DIVIDE(x,y) ((x)>0 ? (x)/(y) : - (-(x)+(y)-1)/(y))
00728
00729
00730 #define MODULO(x,y) ((y)>0 ? POSITIVE_MODULO(x,y) : POSITIVE_MODULO(-x,-y))
00731
00732
00733
00734
00735
00736
00737
00738 #define POSITIVE_MODULO(x,y) ((x) > 0 ? (x)%(y) : \
00739 ((x)%(y) == 0 ? 0 : ((y)-(-(x))%(y))))
00740
00741
00742 extern unsigned int overflow_error;
00743 extern unsigned int simplex_arithmetic_error;
00744 extern unsigned int user_exception_error;
00745 extern unsigned int parser_exception_error;
00746 extern unsigned int any_exception_error;
00747 extern unsigned int the_last_just_thrown_exception;
00748 extern void dump_exception_stack_to_file(FILE * );
00749 extern void dump_exception_stack(void);
00750 extern jmp_buf *push_exception_on_stack(int , const char * , const char * , int );
00751 extern void pop_exception_from_stack(int , const char * , const char * , int );
00752 extern void throw_exception(int , const char * , const char * , int );
00753
00754 #endif
00755
00756
00757