polylib: arithmetique.h Source File

- Main Page
- Classes
- Files

- File List
- File Members

# arithmetique.h

Go to the documentation of this file.

    00001 /*
    00002     This file is part of PolyLib.
    00003
    00004     PolyLib is free software: you can redistribute it and/or modify
    00005     it under the terms of the GNU General Public License as published by
    00006     the Free Software Foundation, either version 3 of the License, or
    00007     (at your option) any later version.
    00008
    00009     PolyLib is distributed in the hope that it will be useful,
    00010     but WITHOUT ANY WARRANTY; without even the implied warranty of
    00011     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    00012     GNU General Public License for more details.
    00013
    00014     You should have received a copy of the GNU General Public License
    00015     along with PolyLib.  If not, see <http://www.gnu.org/licenses/>.
    00016 */
    00017
    00018 /* header file built by cproto */
    00019 #ifndef arithmetique_header_included
    00020 #define arithmetique_header_included
    00021
    00022 /** package arithmetique
    00023  *
    00024  * $Id: arithmetique.h,v 1.24 2007/02/22 09:16:57 skimo Exp $
    00025  *
    00026  * Francois Irigoin, mai 1989
    00027  *
    00028  * Modifications
    00029  *  - rewrite of DIVIDE which was wrong (Remi Triolet, Francois Irigoin,
    00030  *    april 90)
    00031  *  - simplification of POSITIVE_DIVIDE by suppressing one modulo
    00032  *  - B.Meister : added addmul, operation existing in gmp and quite useful
    00033  *    (05-2005)
    00034  */
    00035
    00036 /* We would like linear to be generic about the "integer" type used
    00037  * to represent integer values. Thus Value is defined here. It should
    00038  * be changed to "int" "long" or "long long". In an ideal world,
    00039  * any source modification should be limited to this package.
    00040  *
    00041  * Indeed, we cannot switch easily to bignums that need constructors
    00042  * dans destructors... That would lead to too many modifications...
    00043  * C++ would make things easier and cleaner...
    00044  *
    00045  * Fabien COELHO
    00046  */
    00047
    00048 #include <stdio.h>
    00049 #include <limits.h>   /* Included for getting constants: INT_MAX, etc.. */
    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  * Constants like LONG_LONG_MAX are not defined with ansi options, so they are
    00087  * defined here.
    00088  */
    00089
    00090 #ifndef LONG_LONG_MAX
    00091
    00092 /* would fix on solaris:
    00093  * #define LONG_LONG_MAX LLONG_MAX
    00094  * #define LONG_LONG_MIN LLONG_MIN
    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     /* Mingw or Windows need an incompatible format string. */
    00114 #   define VALUE_FMT "%I64d"
    00115 #else
    00116 #   define VALUE_FMT "%lld"
    00117 #endif
    00118 #define VALUE_CONST(val) (val##LL)
    00119
    00120 /*
    00121  * CAUTION! 'VALUE_MIN' is defined as 'LONG_LONG_MIN +1' so as to preserve the
    00122  * symmetry (-min==max) and to have a NAN value. FC
    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 /* #define VALUE_TO_FLOAT(val) ((float)(val)): Doesn't seem to work with gcc */
    00145 #define VALUE_TO_FLOAT(val) ((float)((int)(val)))
    00146
    00147 /* end LINEAR_VALUE_IS_LONGLONG */
    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 /* end LINEAR_VALUE_IS_LONG */
    00180
    00181 /*
    00182    ######  #        ####     ##     #####
    00183    #       #       #    #   #  #      #
    00184    #####   #       #    #  #    #     #
    00185    #       #       #    #  ######     #
    00186    #       #       #    #  #    #     #
    00187    #       ######   ####   #    #     #
    00188
    00189 */
    00190
    00191 /*
    00192 #elif defined(LINEAR_VALUE_IS_FLOAT)
    00193
    00194 #define LINEAR_VALUE_STRING "float"
    00195 typedef float Value;
    00196 #define VALUE_FMT "%f"
    00197 #define VALUE_CONST(val) (val)
    00198 #define VALUE_MIN FLOAT_MIN
    00199 #define VALUE_MAX FLOAT_MAX
    00200 #define VALUE_ZERO 0.0
    00201 #define VALUE_ONE  1.0
    00202 #define VALUE_MONE -1.0
    00203 #define VALUE_TO_LONG(val) ((long)(val))
    00204 #define VALUE_TO_INT(val) ((int)(val))
    00205 #define VALUE_TO_FLOAT(val) ((float)(val))
    00206 #define VALUE_TO_DOUBLE(val) ((double)(val))
    00207
    00208 */
    00209
    00210 /* end LINEAR_VALUE_IS_FLOAT */
    00211
    00212 /*
    00213    ####   #    #    ##    #####           #   #
    00214   #    #  #    #   #  #   #    #           # #
    00215   #       ######  #    #  #    #         #######
    00216   #       #    #  ######  #####            # #
    00217   #    #  #    #  #    #  #   #           #   #
    00218    ####   #    #  #    #  #    #
    00219
    00220    */
    00221
    00222 /* Char version is used to detect invalid assignments */
    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 /* end LINEAR_VALUE_IS_CHARS */
    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 /* end LINEAR_VALUE_IS_INT */
    00271
    00272 #elif defined(GNUMP)
    00273
    00274 #define LINEAR_VALUE_STRING "gmp"
    00275 typedef mpz_t Value;
    00276 #define VALUE_FMT "%s"
    00277
    00278 /* don't use these, use value_set_si instead ! */
    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 /* ***************** MACROS FOR MANIPULATING VALUES ******************** */
    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 /* Boolean operators on 'Value' */
    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 /* Conditional operations on 'Value' */
    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 /* Basic macros */
    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 /* Boolean operators on 'Value' */
    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 /* Trian operators on 'Value' */
    00407
    00408 #define value_sign(val)      (mpz_sgn(val))
    00409 #define value_compare(v1,v2) (mpz_cmp((v1),(v2)))
    00410
    00411 /* Binary operations on 'Value' */
    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 /* Conditional operations on 'Value' */
    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 /* 'Value' set to longlong|long|float|char *|int */
    00456 /* Basic Macros */
    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 /* Cast to 'Value' */
    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 /* Boolean operators on 'Value' */
    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 /* Trian operators on 'Value' */
    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 /* Binary operators on 'Value' */
    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)) /* direct! */
    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 /* Binary operations on 'Value' */
    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)) /* direct! */
    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 /* Unary operators on 'Value' */
    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 /* Conditional operations on 'Value' */
    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 /* 'Value' set to |longlong|long|float|char *|int */
    00566
    00567
    00568 /* *********************** PROTECTED MULTIPLICATION ********************** */
    00569
    00570 #include "arithmetic_errors.h"
    00571
    00572 /* (|v| < MAX / |w|) => v*w is okay
    00573  * I could check ((v*w)/w)==v but a tmp would be useful
    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 /* is a software idiv is assumed, quick check performed first
    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 /* protected versions
    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 /* whether the default is protected or not
    00600  * this define makes no sense any more... well, doesn't matter. FC.
    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 /* I do enforce the protection whatever requested:-)
    00608  * prints out a message and throws the exception, hoping
    00609  * that some valid CATCH waits for it upwards.
    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 /* was:
    00617  * #define value_mult(v,w) value_direct_multiply(v,w)
    00618  * #define value_product(v,w) value_direct_product(v,w)
    00619  * could be: protected versions...
    00620  */
    00621 #endif
    00622
    00623 /******************************************************* STATIC VALUE DEBUG */
    00624
    00625 /* LINEAR_VALUE_IS_CHARS is used for type checking.
    00626  * some operations are not allowed on (char*), thus
    00627  * they are switched to some other operation here...
    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 /* for backward compatibility */
    00695 #define value_substract(ref,val1,val2) (value_subtract((ref),(val1),(val2)))
    00696
    00697 /* valeur absolue
    00698  */
    00699 #ifndef ABS
    00700 #define ABS(x) (((x)>=0) ? (x) : -(x))
    00701 #endif
    00702
    00703 /* minimum et maximum
    00704  * if they are defined somewhere else, they are very likely
    00705  * to be defined the same way. Thus the previous def is not overwritten.
    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 /* signe d'un entier: -1, 0 ou 1 */
    00715 #define SIGN(x) (((x)>0)? 1 : ((x)==0? 0 : -1))
    00716
    00717 /* division avec reste toujours positif
    00718  * basee sur les equations:
    00719  * a/(-b) = - (a/b)
    00720  * (-a)/b = - ((a+b-1)/b)
    00721  * ou a et b sont des entiers positifs
    00722  */
    00723 #define DIVIDE(x,y) ((y)>0? POSITIVE_DIVIDE(x,y) : \
    00724                      -POSITIVE_DIVIDE((x),(-(y))))
    00725
    00726 /* division avec reste toujours positif quand y est positif: assert(y>=0) */
    00727 #define POSITIVE_DIVIDE(x,y) ((x)>0 ? (x)/(y) : - (-(x)+(y)-1)/(y))
    00728
    00729 /* modulo a resultat toujours positif */
    00730 #define MODULO(x,y) ((y)>0 ? POSITIVE_MODULO(x,y) : POSITIVE_MODULO(-x,-y))
    00731
    00732 /* modulo par rapport a un nombre positif: assert(y>=0)
    00733  *
    00734  * Ce n'est pas la macro la plus efficace que j'aie jamais ecrite: il faut
    00735  * faire, dans le pire des cas, deux appels a la routine .rem, qui n'est
    00736  * surement pas plus cablee que la division ou la multiplication
    00737  */
    00738 #define POSITIVE_MODULO(x,y) ((x) > 0 ? (x)%(y) : \
    00739                               ((x)%(y) == 0 ? 0 : ((y)-(-(x))%(y))))
    00740
    00741 /* errors.c */
    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 * /*f*/);
    00749 extern void dump_exception_stack(void);
    00750 extern jmp_buf *push_exception_on_stack(int /*what*/, const char * /*function*/, const char * /*file*/, int /*line*/);
    00751 extern void pop_exception_from_stack(int /*what*/, const char * /*function*/, const char * /*file*/, int /*line*/);
    00752 extern void throw_exception(int /*what*/, const char * /*function*/, const char * /*file*/, int /*line*/);
    00753
    00754 #endif /* arithmetique_header_included */
    00755
    00756
    00757