Main Page | Class List | File List | Class Members | File Members

arithmetique.h

Go to the documentation of this file.
00001 /* header file built by cproto */
00002 #ifndef arithmetique_header_included
00003 #define arithmetique_header_included
00004 
00005 /** package arithmetique
00006  *
00007  * $Id: arithmetique.h,v 1.24 2007/02/22 09:16:57 skimo Exp $
00008  *
00009  * Francois Irigoin, mai 1989
00010  *
00011  * Modifications
00012  *  - rewrite of DIVIDE which was wrong (Remi Triolet, Francois Irigoin, 
00013  *    april 90)
00014  *  - simplification of POSITIVE_DIVIDE by suppressing one modulo
00015  *  - B.Meister : added addmul, operation existing in gmp and quite useful 
00016  *    (05-2005)
00017  */
00018 
00019 /* We would like linear to be generic about the "integer" type used
00020  * to represent integer values. Thus Value is defined here. It should
00021  * be changed to "int" "long" or "long long". In an ideal world,
00022  * any source modification should be limited to this package.
00023  *
00024  * Indeed, we cannot switch easily to bignums that need constructors 
00025  * dans destructors... That would lead to too many modifications...
00026  * C++ would make things easier and cleaner...
00027  *
00028  * Fabien COELHO
00029  */
00030 
00031 #include <stdio.h>
00032 #include <limits.h>   /* Included for getting constants: INT_MAX, etc.. */
00033 
00034 #ifdef GNUMP
00035 #include <gmp.h>
00036 #include <stdlib.h>
00037 #include <string.h>
00038 #ifndef mp_get_memory_functions
00039 #if defined(__cplusplus)
00040 extern "C" {
00041 #endif
00042 void mp_get_memory_functions(
00043                 void *(**alloc_func_ptr) (size_t),
00044                 void *(**realloc_func_ptr) (void *, size_t, size_t),
00045                 void (**free_func_ptr) (void *, size_t));
00046 #if defined(__cplusplus)
00047 }
00048 #endif
00049 #endif
00050 #endif 
00051 
00052 #ifdef CLN
00053 #include <sstream>
00054 #define WANT_OBFUSCATING_OPERATORS
00055 #include <cln/cln.h>
00056 #endif
00057 
00058 /* 
00059    #        ####   #    #   ####           #        ####   #    #   ####
00060    #       #    #  ##   #  #    #          #       #    #  ##   #  #    #
00061    #       #    #  # #  #  #               #       #    #  # #  #  #
00062    #       #    #  #  # #  #  ###          #       #    #  #  # #  #  ###
00063    #       #    #  #   ##  #    #          #       #    #  #   ##  #    #
00064    ######   ####   #    #   ####           ######   ####   #    #   ####
00065    
00066 */
00067 
00068 /* 
00069  * Constants like LONG_LONG_MAX are not defined with ansi options, so they are
00070  * defined here. 
00071  */  
00072 
00073 #ifndef LONG_LONG_MAX
00074 
00075 /* would fix on solaris:
00076  * #define LONG_LONG_MAX LLONG_MAX
00077  * #define LONG_LONG_MIN LLONG_MIN
00078  */
00079 
00080 #ifndef __LONG_LONG_MAX__
00081 #define __LONG_LONG_MAX__ 9223372036854775807LL
00082 #endif
00083 #undef LONG_LONG_MAX
00084 #define LONG_LONG_MAX __LONG_LONG_MAX__
00085 #undef LONG_LONG_MIN
00086 #define LONG_LONG_MIN (-LONG_LONG_MAX-1)
00087 #undef ULONG_LONG_MAX
00088 #define ULONG_LONG_MAX (LONG_LONG_MAX * 2ULL + 1)
00089 #endif
00090 
00091 #if defined(LINEAR_VALUE_IS_LONGLONG)
00092 
00093 #define LINEAR_VALUE_STRING "long long int"
00094 typedef long long int Value;
00095 #if defined(WIN32) && !defined(unix)
00096     /* Mingw or Windows need an incompatible format string. */
00097 #   define VALUE_FMT "%I64d"
00098 #else
00099 #   define VALUE_FMT "%lld"
00100 #endif
00101 #define VALUE_CONST(val) (val##LL) 
00102 
00103 /* 
00104  * CAUTION! 'VALUE_MIN' is defined as 'LONG_LONG_MIN +1' so as to preserve the
00105  * symmetry (-min==max) and to have a NAN value. FC 
00106  */ 
00107 
00108 #define VALUE_NAN LONG_LONG_MIN
00109 #define VALUE_MIN (LONG_LONG_MIN+1LL)
00110 #define VALUE_MAX LONG_LONG_MAX
00111 #define VALUE_SQRT_MIN long_to_value(LONG_MIN) 
00112 #define VALUE_SQRT_MAX long_to_value(LONG_MAX)
00113 #define VALUE_ZERO (0LL)
00114 #define VALUE_ONE  (1LL)
00115 #define VALUE_MONE (-1LL)
00116 
00117 #define VALUE_TO_LONG(val) \
00118     ((long)((val)>(Value)LONG_MIN&&(val)<=(Value)LONG_MAX)?\
00119      (val):(THROW(overflow_error), LONG_MIN))
00120 
00121 #define VALUE_TO_INT(val) \
00122     ((int)((val)>(Value)INT_MIN&&(val)<=(Value)INT_MAX)?\
00123      (val):(THROW(overflow_error), INT_MIN))
00124 
00125 #define VALUE_TO_DOUBLE(val) ((double)(val))
00126 
00127 /* #define VALUE_TO_FLOAT(val) ((float)(val)): Doesn't seem to work with gcc */
00128 #define VALUE_TO_FLOAT(val) ((float)((int)(val)))
00129 
00130 /* end LINEAR_VALUE_IS_LONGLONG */
00131 
00132 /* 
00133  
00134    #        ####   #    #   ####
00135    #       #    #  ##   #  #    #
00136    #       #    #  # #  #  #
00137    #       #    #  #  # #  #  ###
00138    #       #    #  #   ##  #    #
00139    ######   ####   #    #   ####
00140  
00141 */
00142 
00143 #elif defined(LINEAR_VALUE_IS_LONG)
00144 
00145 #define LINEAR_VALUE_STRING "long int"
00146 typedef long Value;
00147 #define VALUE_FMT "%ld"
00148 #define VALUE_CONST(val) (val##L)
00149 #define VALUE_NAN LONG_MIN
00150 #define VALUE_MIN (LONG_MIN+1L)
00151 #define VALUE_MAX LONG_MAX
00152 #define VALUE_SQRT_MIN int_to_value(INT_MIN)
00153 #define VALUE_SQRT_MAX int_to_value(INT_MAX)
00154 #define VALUE_ZERO 0L
00155 #define VALUE_ONE  1L
00156 #define VALUE_MONE -1L
00157 #define VALUE_TO_LONG(val) (val)
00158 #define VALUE_TO_INT(val) ((int)(val))
00159 #define VALUE_TO_FLOAT(val) ((float)(val))
00160 #define VALUE_TO_DOUBLE(val) ((double)(val))
00161 
00162 /* end LINEAR_VALUE_IS_LONG */
00163 
00164 /* 
00165    ######  #        ####     ##     #####
00166    #       #       #    #   #  #      #
00167    #####   #       #    #  #    #     #
00168    #       #       #    #  ######     #
00169    #       #       #    #  #    #     #
00170    #       ######   ####   #    #     #
00171  
00172 */
00173 
00174 /*
00175 #elif defined(LINEAR_VALUE_IS_FLOAT)
00176 
00177 #define LINEAR_VALUE_STRING "float"
00178 typedef float Value;
00179 #define VALUE_FMT "%f"
00180 #define VALUE_CONST(val) (val)
00181 #define VALUE_MIN FLOAT_MIN
00182 #define VALUE_MAX FLOAT_MAX
00183 #define VALUE_ZERO 0.0
00184 #define VALUE_ONE  1.0
00185 #define VALUE_MONE -1.0
00186 #define VALUE_TO_LONG(val) ((long)(val))
00187 #define VALUE_TO_INT(val) ((int)(val))
00188 #define VALUE_TO_FLOAT(val) ((float)(val))
00189 #define VALUE_TO_DOUBLE(val) ((double)(val))
00190 
00191 */
00192 
00193 /* end LINEAR_VALUE_IS_FLOAT */
00194 
00195 /*
00196    ####   #    #    ##    #####           #   #
00197   #    #  #    #   #  #   #    #           # #
00198   #       ######  #    #  #    #         #######
00199   #       #    #  ######  #####            # #
00200   #    #  #    #  #    #  #   #           #   #
00201    ####   #    #  #    #  #    #
00202   
00203    */
00204 
00205 /* Char version is used to detect invalid assignments */
00206 
00207 #elif defined(LINEAR_VALUE_IS_CHARS)
00208 
00209 #define LINEAR_VALUE_STRING "char"
00210 typedef union { char *s; long l; int i; float f; double d;} Value;
00211 #define VALUE_FMT "%s"
00212 #define VALUE_CONST(val) ((Value)(val))
00213 #define VALUE_NAN ((Value)(long)0xdadeebee)
00214 #define VALUE_MIN ((Value)(long)0xdeadbeef)
00215 #define VALUE_MAX ((Value)(long)0xfeedabee)
00216 #define VALUE_ZERO ((Value)0)
00217 #define VALUE_ONE  ((Value)1)
00218 #define VALUE_MONE ((Value)-1)
00219 #define VALUE_TO_LONG(val) (val.l)
00220 #define VALUE_TO_INT(val) (val.i)
00221 #define VALUE_TO_FLOAT(val) (val.f)
00222 #define VALUE_TO_DOUBLE(val) (val.d)
00223 
00224 /* end LINEAR_VALUE_IS_CHARS */
00225 
00226 /*
00227     #    #    #   #####
00228     #    ##   #     #
00229     #    # #  #     #
00230     #    #  # #     #
00231     #    #   ##     #
00232     #    #    #     #
00233 
00234 */
00235 
00236 #elif defined(LINEAR_VALUE_IS_INT)
00237 
00238 #define LINEAR_VALUE_STRING "int"
00239 typedef int Value;
00240 #define VALUE_FMT "%d"
00241 #define VALUE_CONST(val) (val)
00242 #define VALUE_NAN INT_MIN
00243 #define VALUE_MIN (INT_MIN+1)
00244 #define VALUE_MAX INT_MAX
00245 #define VALUE_ZERO  0
00246 #define VALUE_ONE   1
00247 #define VALUE_MONE -1
00248 #define VALUE_TO_LONG(val) ((long)(val))
00249 #define VALUE_TO_INT(val) ((int)(val))
00250 #define VALUE_TO_FLOAT(val) ((float)(val))
00251 #define VALUE_TO_DOUBLE(val) ((double)(val))
00252 
00253 /* end LINEAR_VALUE_IS_INT */
00254 
00255 #elif defined(GNUMP)
00256 
00257 #define LINEAR_VALUE_STRING "gmp"
00258 typedef mpz_t Value;
00259 #define VALUE_FMT "%s"
00260 
00261 /* don't use these, use value_set_si instead ! */
00262 #undef VALUE_ZERO
00263 #undef VALUE_ONE
00264 #undef VALUE_MONE
00265 #define VALUE_TO_LONG(val) (mpz_get_si(val))
00266 #define VALUE_TO_INT(val) ((int)mpz_get_si(val))
00267 #define VALUE_TO_FLOAT(val) ((float)((int)mpz_get_si(val)))
00268 #define VALUE_TO_DOUBLE(val) (mpz_get_d(val))
00269 
00270 #elif defined(CLN)
00271 
00272 #define LINEAR_VALUE_STRING "cln"
00273 typedef cln::cl_I Value;
00274 #define VALUE_FMT "%s"
00275 
00276 #define VALUE_TO_INT(val) (cln::cl_I_to_int(val))
00277 #define VALUE_TO_DOUBLE(val) (cln::double_approx(val))
00278 
00279 #endif 
00280 
00281 /* ***************** MACROS FOR MANIPULATING VALUES ******************** */
00282 
00283 #if defined(CLN)
00284 
00285 #define value_init(val)         ((val).word = ((cln::cl_uint)cl_FN_tag) << cl_tag_shift)
00286 #define value_assign(v1,v2)     ((v1) = (v2))
00287 #define value_set_si(val,i)     ((val) = (i))    
00288 #define value_set_double(val,d) ((val) = cln::truncate1(cln::cl_R(d)))
00289 #define value_clear(val)        ((val) = 0)
00290 #define value_read(val,str)     ((val) = (str))
00291 #define value_print(Dst,fmt,val)  {std::ostringstream strm; strm << val; \
00292                                    fprintf((Dst),(fmt),strm.str().c_str()); \
00293                                   }
00294 #define value_swap(v1,v2)          {Value tmp; tmp = v2; \
00295                                     v2 = v1; v1 = tmp;   \
00296                                    }
00297 
00298 /* Boolean operators on 'Value' */
00299 
00300 #define value_eq(v1,v2) ((v1)==(v2))
00301 #define value_ne(v1,v2) ((v1)!=(v2))
00302 #define value_gt(v1,v2) ((v1)>(v2))
00303 #define value_ge(v1,v2) ((v1)>=(v2))
00304 #define value_lt(v1,v2) ((v1)<(v2))
00305 #define value_le(v1,v2) ((v1)<=(v2))
00306 
00307 #define value_abs_eq(v1,v2) (cln::abs(v1)==cln::abs(v2))
00308 #define value_abs_ne(v1,v2) (cln::abs(v1)!=cln::abs(v2))
00309 #define value_abs_gt(v1,v2) (cln::abs(v1)>cln::abs(v2))
00310 #define value_abs_ge(v1,v2) (cln::abs(v1)>=cln::abs(v2))
00311 #define value_abs_lt(v1,v2) (cln::abs(v1)<cln::abs(v2))
00312 #define value_abs_le(v1,v2) (cln::abs(v1)<=cln::abs(v2))
00313 
00314 #define value_sign(val)      (cln::signum(val))
00315 #define value_compare(v1,v2) (cln::compare((v1),(v2)))
00316 
00317 #define value_addto(ref,val1,val2)      ((ref) = (val1)+(val2))
00318 #define value_add_int(ref,val,vint)     ((ref) = (val)+(vint))
00319 #define value_addmul(ref, val1, val2)   ((ref) += (val1)*(val2))
00320 #define value_increment(ref,val)        ((ref) = (val)+1)
00321 #define value_multiply(ref,val1,val2)   ((ref) = (val1)*(val2))
00322 #define value_subtract(ref,val1,val2)   ((ref) = (val1)-(val2))
00323 #define value_sub_int(ref,val1,val2)    ((ref) = (val1)-(val2))
00324 #define value_decrement(ref,val)        ((ref) = (val)-1)
00325 #define value_division(ref,val1,val2)   ((ref) = cln::truncate1(val1,val2))
00326 #define value_divexact(ref,val1,val2)   ((ref) = cln::exquo(val1,val2))
00327 #define value_modulus(ref,val1,val2)    ((ref) = cln::truncate2(val1,val2).remainder)
00328 #define value_pdivision(ref,val1,val2)  ((ref) = cln::floor1(val1,val2))
00329 #define value_pmodulus(ref,val1,val2)   ((ref) = cln::floor2(val1,val2).remainder)
00330 #define value_oppose(ref,val)           ((ref) = -(val))
00331 #define value_absolute(ref,val)         ((ref) = cln::abs(val))
00332 #define value_minimum(ref,val1,val2)    ((ref) = cln::min((val1),(val2)))
00333 #define value_maximum(ref,val1,val2)    ((ref) = cln::max((val1),(val2)))
00334 #define value_gcd(ref,val1,val2)        ((ref) = cln::gcd((val1),(val2)))
00335 #define value_lcm(ref,val1,val2)        ((ref) = cln::lcm((val1),(val2)))
00336 #define value_orto(ref,val1,val2)       ((ref) = (val1)|(val2))
00337 #define value_andto(ref,val1,val2)      ((ref) = (val1)&(val2))
00338 
00339 /* Conditional operations on 'Value' */
00340 
00341 #define value_pos_p(val)         ((val) >  0)
00342 #define value_neg_p(val)         ((val) <  0)
00343 #define value_posz_p(val)        ((val) >= 0)
00344 #define value_negz_p(val)        ((val) <= 0)
00345 #define value_zero_p(val)        ((val) == 0)
00346 #define value_notzero_p(val)     ((val) != 0)
00347 #define value_one_p(val)         ((val) == 1)
00348 #define value_notone_p(val)      ((val) != 1)
00349 #define value_mone_p(val)        ((val) == -1)
00350 #define value_notmone_p(val)     ((val) != -1)
00351 #define value_cmp_si(val, n)     (cln::compare(val,n))
00352 
00353 #elif defined(GNUMP)
00354 
00355 /* Basic macros */
00356 
00357 #define value_init(val)        (mpz_init((val)))
00358 #define value_assign(v1,v2)    (mpz_set((v1),(v2)))
00359 #define value_set_si(val,i)    (mpz_set_si((val),(i)))    
00360 #define value_set_double(val,d)(mpz_set_d((val),(d)))
00361 #define value_clear(val)       (mpz_clear((val)))
00362 #define value_read(val,str)    (mpz_set_str((val),(str),10))
00363 typedef void (*value_print_gmp_free_t)(void *, size_t);
00364 #define value_print(Dst,fmt,val)  {char *str; \
00365                                 value_print_gmp_free_t gmp_free; \
00366                                 str = mpz_get_str(0,10,(val)); \
00367                                 fprintf((Dst),(fmt),str); \
00368                                 mp_get_memory_functions(NULL, NULL, &gmp_free); \
00369                                 (*gmp_free) (str, strlen(str)+1); \
00370                               }
00371 #define value_swap(val1,val2) (mpz_swap(val1, val2))
00372                                              
00373 /* Boolean operators on 'Value' */
00374 
00375 #define value_eq(v1,v2) (mpz_cmp((v1),(v2)) == 0)
00376 #define value_ne(v1,v2) (mpz_cmp((v1),(v2)) != 0)
00377 #define value_gt(v1,v2) (mpz_cmp((v1),(v2))  > 0)
00378 #define value_ge(v1,v2) (mpz_cmp((v1),(v2)) >= 0)
00379 #define value_lt(v1,v2) (mpz_cmp((v1),(v2))  < 0)
00380 #define value_le(v1,v2) (mpz_cmp((v1),(v2)) <= 0)
00381 
00382 #define value_abs_eq(v1,v2) (mpz_cmpabs((v1),(v2)) == 0)
00383 #define value_abs_ne(v1,v2) (mpz_cmpabs((v1),(v2)) != 0)
00384 #define value_abs_gt(v1,v2) (mpz_cmpabs((v1),(v2))  > 0)
00385 #define value_abs_ge(v1,v2) (mpz_cmpabs((v1),(v2)) >= 0)
00386 #define value_abs_lt(v1,v2) (mpz_cmpabs((v1),(v2))  < 0)
00387 #define value_abs_le(v1,v2) (mpz_cmpabs((v1),(v2)) <= 0)
00388 
00389 /* Trian operators on 'Value' */
00390 
00391 #define value_sign(val)      (mpz_sgn(val))
00392 #define value_compare(v1,v2) (mpz_cmp((v1),(v2)))
00393 
00394 /* Binary operations on 'Value' */
00395 
00396 #define value_addto(ref,val1,val2)     (mpz_add((ref),(val1),(val2)))
00397 #define value_add_int(ref,val,vint)     (mpz_add_ui((ref),(val),(long)(vint)))
00398 #define value_addmul(ref, val1, val2)   (mpz_addmul((ref), (val1), (val2)))
00399 #define value_increment(ref,val)       (mpz_add_ui((ref),(val),1))
00400 #define value_multiply(ref,val1,val2)  (mpz_mul((ref),(val1),(val2)))
00401 #define value_subtract(ref,val1,val2) (mpz_sub((ref),(val1),(val2)))
00402 #define value_sub_int(ref,val,vint)     (mpz_sub_ui((ref),(val),(long)(vint)))
00403 #define value_decrement(ref,val)       (mpz_sub_ui((ref),(val),1))
00404 #define value_division(ref,val1,val2)  (mpz_tdiv_q((ref),(val1),(val2)))
00405 #define value_divexact(ref,val1,val2)  (mpz_divexact((ref),(val1),(val2)))
00406 #define value_modulus(ref,val1,val2)   (mpz_tdiv_r((ref),(val1),(val2)))
00407 #define value_pdivision(ref,val1,val2) (mpz_fdiv_q((ref),(val1),(val2)))
00408 #define value_pmodulus(ref,val1,val2)  (mpz_fdiv_r((ref),(val1),(val2)))
00409 #define value_oppose(ref,val)          (mpz_neg((ref),(val)))
00410 #define value_absolute(ref,val)        (mpz_abs((ref),(val)))
00411 #define value_minimum(ref,val1,val2)   (value_le((val1),(val2)) ?  \
00412                                         mpz_set((ref),(val1)) :    \
00413                                         mpz_set((ref),(val2)))  
00414 #define value_maximum(ref,val1,val2)   (value_ge((val1),(val2)) ?  \
00415                                         mpz_set((ref),(val1)) :    \
00416                                         mpz_set((ref),(val2)))  
00417 #define value_gcd(ref,val1,val2)        (mpz_gcd(ref,val1,val2))
00418 #define value_lcm(ref,val1,val2)        (mpz_lcm(ref,val1,val2))
00419 #define value_orto(ref,val1,val2)      (mpz_ior((ref),(val1),(val2)))
00420 #define value_andto(ref,val1,val2)     (mpz_and((ref),(val1),(val2)))
00421 
00422 /* Conditional operations on 'Value' */
00423 
00424 #define value_pos_p(val)         (mpz_sgn(val) >  0)
00425 #define value_neg_p(val)         (mpz_sgn(val) <  0)
00426 #define value_posz_p(val)        (mpz_sgn(val) >= 0)
00427 #define value_negz_p(val)        (mpz_sgn(val) <= 0)
00428 #define value_zero_p(val)        (mpz_sgn(val) == 0)
00429 #define value_notzero_p(val)     (mpz_sgn(val) != 0)
00430 #define value_one_p(val)         (mpz_cmp_si(val,1) == 0)
00431 #define value_notone_p(val)      (mpz_cmp_si(val,1) != 0)
00432 #define value_mone_p(val)        (mpz_cmp_si(val,-1) ==0)
00433 #define value_notmone_p(val)     (mpz_cmp_si(val,-1) !=0)
00434 #define value_cmp_si(val, n)     (mpz_cmp_si(val,n))
00435 
00436 /* ************************************************************************* */
00437 
00438 #else /* 'Value' set to longlong|long|float|char *|int */                                       
00439 /* Basic Macros */                                  
00440 
00441 #define value_init(val)            ((val) = 0)
00442 #define value_assign(v1,v2)        ((v1)  = (v2))
00443 #define value_set_si(val,i)        ((val) = (Value)(i))   
00444 #define value_set_double(val,d)    ((val) = (Value)(d)) 
00445 #define value_clear(val)           ((val) = 0)
00446 #define value_read(val,str)        (sscanf((str),VALUE_FMT,&(val)))
00447 #define value_print(Dst,fmt,val)   (fprintf((Dst),(fmt),(val)))
00448 #define value_swap(v1,v2)          {Value tmp; tmp = v2; \
00449                                     v2 = v1; v1 = tmp;   \
00450                                    }
00451 /* Cast to 'Value' */
00452 
00453 #define int_to_value(i) ((Value)(i))
00454 #define long_to_value(l) ((Value)(l))
00455 #define float_to_value(f) ((Value)(f))
00456 #define double_to_value(d) ((Value)(d))
00457    
00458 /* Boolean operators on 'Value' */
00459 
00460 #define value_eq(v1,v2) ((v1)==(v2))
00461 #define value_ne(v1,v2) ((v1)!=(v2))
00462 #define value_gt(v1,v2) ((v1)>(v2))
00463 #define value_ge(v1,v2) ((v1)>=(v2))
00464 #define value_lt(v1,v2) ((v1)<(v2))
00465 #define value_le(v1,v2) ((v1)<=(v2))
00466 
00467 #define value_abs_eq(v1,v2) (value_abs(v1)==value_abs(v2))
00468 #define value_abs_ne(v1,v2) (value_abs(v1)!=value_abs(v2))
00469 #define value_abs_gt(v1,v2) (value_abs(v1)>value_abs(v2))
00470 #define value_abs_ge(v1,v2) (value_abs(v1)>=value_abs(v2))
00471 #define value_abs_lt(v1,v2) (value_abs(v1)<value_abs(v2))
00472 #define value_abs_le(v1,v2) (value_abs(v1)<=value_abs(v2))
00473 
00474 /* Trian operators on 'Value' */
00475 
00476 #define value_sign(v) (value_eq(v,VALUE_ZERO)?0:value_lt(v,VALUE_ZERO)?-1:1)
00477 #define value_compare(v1,v2) (value_eq(v1,v2)?0:value_lt(v1,v2)?-1:1)
00478 
00479 /* Binary operators on 'Value' */
00480 
00481 #define value_plus(v1,v2)               ((v1)+(v2))
00482 #define value_div(v1,v2)                ((v1)/(v2))
00483 #define value_mod(v1,v2)                ((v1)%(v2))
00484 #define value_direct_multiply(v1,v2)    ((v1)*(v2)) /* direct! */
00485 #define value_minus(v1,v2)              ((v1)-(v2))
00486 #define value_pdiv(v1,v2)               (DIVIDE((v1),(v2)))
00487 #define value_pmod(v1,v2)               (MODULO((v1),(v2)))
00488 #define value_min(v1,v2)                (value_le((v1),(v2))? (v1): (v2))
00489 #define value_max(v1,v2)                (value_ge((v1),(v2))? (v1): (v2))
00490 #define value_or(v1,v2)                 ((v1)|(v2))
00491 #define value_and(v1,v2)                ((v1)&(v2))
00492 #define value_lshift(v1,v2)             ((v1)<<(v2))
00493 #define value_rshift(v1,v2)             ((v1)>>(v2))
00494                                   
00495 /* Binary operations on 'Value' */ 
00496 
00497 #define value_addto(ref,val1,val2)      ((ref) = (val1)+(val2))
00498 #define value_add_int(ref,val,vint)     ((ref) = (val)+(Value)(vint))
00499 #define value_addmul(ref, val1, val2)   ((ref) += (val1)*(val2))
00500 #define value_increment(ref,val)        ((ref) = (val)+VALUE_ONE)
00501 #define value_direct_product(ref,val1,val2) ((ref) = (val1)*(val2)) /* direct! */
00502 #define value_multiply(ref,val1,val2)   ((ref) = value_mult((val1),(val2)))
00503 #define value_subtract(ref,val1,val2)   ((ref) = (val1)-(val2))
00504 #define value_sub_int(ref,val,vint)     ((ref) = (val)-(Value)(vint))
00505 #define value_decrement(ref,val)        ((ref) = (val)-VALUE_ONE)
00506 #define value_division(ref,val1,val2)   ((ref) = (val1)/(val2))
00507 #define value_divexact(ref,val1,val2)   ((ref) = (val1)/(val2))
00508 #define value_modulus(ref,val1,val2)    ((ref) = (val1)%(val2))
00509 #define value_pdivision(ref,val1,val2)  ((ref) = value_pdiv((val1),(val2)))
00510 #define value_pmodulus(ref,val1,val2)   ((ref) = value_pmod((val1),(val2)))
00511 #define value_oppose(ref,val)           ((ref) = value_uminus((val)))
00512 #define value_absolute(ref,val)         ((ref) = value_abs((val)))
00513 #define value_minimum(ref,val1,val2)    ((ref) = value_min((val1),(val2)))
00514 #define value_maximum(ref,val1,val2)    ((ref) = value_max((val1),(val2)))
00515 #define value_gcd(ref,val1,val2)        Gcd((val1),(val2),&(ref))
00516 #define value_lcm(ref,val1,val2)        Lcm3((val1),(val2),&(ref))
00517 #define value_orto(ref,val1,val2)       ((ref) = (val1)|(val2))
00518 #define value_andto(ref,val1,val2)      ((ref) = (val1)&(val2))
00519 
00520 /* Unary operators on 'Value' */
00521 
00522 #define value_uminus(val)  (-(val))
00523 #define value_not(val)  (~(val))
00524 #define value_abs(val) (value_posz_p(val)? \
00525     (val) :                                \
00526     (value_ne((val), VALUE_NAN) ?          \
00527      value_uminus(val) :                   \
00528     (THROW (overflow_error), VALUE_NAN )))
00529 
00530 /* Conditional operations on 'Value' */
00531 
00532 #define value_pos_p(val)      value_gt(val,VALUE_ZERO)
00533 #define value_neg_p(val)      value_lt(val,VALUE_ZERO)
00534 #define value_posz_p(val)     value_ge(val,VALUE_ZERO)
00535 #define value_negz_p(val)     value_le(val,VALUE_ZERO)
00536 #define value_zero_p(val)     value_eq(val,VALUE_ZERO)
00537 #define value_notzero_p(val)  value_ne(val,VALUE_ZERO)
00538 #define value_one_p(val)      value_eq(val,VALUE_ONE)
00539 #define value_notone_p(val)   value_ne(val,VALUE_ONE)
00540 #define value_mone_p(val)     value_eq(val,VALUE_MONE)
00541 #define value_notmone_p(val)  value_ne(val,VALUE_MONE)
00542 #define value_cmp_si(val, n)  (val - (n))
00543 #define value_min_p(val)      value_eq(val,VALUE_MIN)
00544 #define value_max_p(val)      value_eq(val,VALUE_MAX)
00545 #define value_notmin_p(val)   value_ne(val,VALUE_MIN)
00546 #define value_notmax_p(val)   value_ne(val,VALUE_MAX)
00547 
00548 #endif /* 'Value' set to |longlong|long|float|char *|int */
00549 
00550 
00551 /* *********************** PROTECTED MULTIPLICATION ********************** */
00552 
00553 #include "arithmetic_errors.h"
00554 
00555 /* (|v| < MAX / |w|) => v*w is okay
00556  * I could check ((v*w)/w)==v but a tmp would be useful
00557  */
00558 #define value_protected_hard_idiv_multiply(v,w,throw)           \
00559   ((value_zero_p(w) || value_zero_p(v))? VALUE_ZERO:            \
00560    value_lt(value_abs(v),value_div(VALUE_MAX,value_abs(w)))?    \
00561    value_direct_multiply(v,w): (throw, VALUE_NAN))
00562 
00563 /* is a software idiv is assumed, quick check performed first
00564  */
00565 #if defined(LINEAR_VALUE_ASSUME_SOFTWARE_IDIV)
00566 #define value_protected_multiply(v,w,throw)                                   \
00567   ((value_le(v,VALUE_SQRT_MAX) && value_le(w,VALUE_SQRT_MAX) &&               \
00568    value_ge(v,VALUE_SQRT_MIN) && value_ge(w,VALUE_SQRT_MIN))?                 \
00569    value_direct_multiply(v,w): value_protected_hard_idiv_multiply(v,w,throw))
00570 #else
00571 #define value_protected_multiply(v,w,throw)             \
00572    value_protected_hard_idiv_multiply(v,w,throw)
00573 #endif
00574 
00575 /* protected versions
00576  */
00577 #define value_protected_mult(v,w)                               \
00578     value_protected_multiply(v,w,THROW(overflow_error))
00579 #define value_protected_product(v,w)            \
00580     v=value_protected_mult(v,w)
00581 
00582 /* whether the default is protected or not 
00583  * this define makes no sense any more... well, doesn't matter. FC.
00584  */
00585 #if defined(LINEAR_VALUE_PROTECT_MULTIPLY)
00586 #define value_mult(v,w) value_protected_mult(v,w)
00587 #define value_product(v,w) value_protected_product(v,w)
00588 #else
00589 
00590 /* I do enforce the protection whatever requested:-)
00591  * prints out a message and throws the exception, hoping
00592  * that some valid CATCH waits for it upwards. 
00593  */
00594 #define value_mult(v,w)                                                       \
00595   value_protected_multiply(v,w,                                               \
00596     (fprintf(stderr,"[value_mult] value overflow!\n"),THROW(overflow_error)))
00597 #define value_product(v,w) v=value_mult(v,w)
00598 
00599 /* was:
00600  * #define value_mult(v,w) value_direct_multiply(v,w)
00601  * #define value_product(v,w) value_direct_product(v,w)
00602  * could be: protected versions...
00603  */
00604 #endif
00605 
00606 /******************************************************* STATIC VALUE DEBUG */
00607 
00608 /* LINEAR_VALUE_IS_CHARS is used for type checking.
00609  * some operations are not allowed on (char*), thus
00610  * they are switched to some other operation here...
00611  */
00612 #if defined(LINEAR_VALUE_IS_CHARS)
00613 #define value_fake_binary(v1,v2) ((Value)((v1).i+(v2).i))
00614 #define value_bool_binary(v1,v2) ((int)((v1).i+(v2).i))
00615 #undef float_to_value
00616 #define float_to_value(f) ((Value)f)
00617 #undef double_to_value
00618 #define double_to_value(f) ((Value)f)
00619 #undef value_uminus
00620 #define value_uminus(v) (v)
00621 #undef value_mult
00622 #define value_mult(v1,v2) value_fake_binary(v1,v2)
00623 #undef value_mod
00624 #define value_mod(v1,v2) value_fake_binary(v1,v2)
00625 #undef value_ge
00626 #define value_ge(v1,v2) value_bool_binary(v1,v2)
00627 #undef value_gt
00628 #define value_gt(v1,v2) value_bool_binary(v1,v2)
00629 #undef value_le
00630 #define value_le(v1,v2) value_bool_binary(v1,v2)
00631 #undef value_lt
00632 #define value_lt(v1,v2) value_bool_binary(v1,v2)
00633 #undef value_ne
00634 #define value_ne(v1,v2) value_bool_binary(v1,v2)
00635 #undef value_eq
00636 #define value_eq(v1,v2) value_bool_binary(v1,v2)
00637 #undef value_plus
00638 #define value_plus(v1,v2) value_fake_binary(v1,v2)
00639 #undef value_minus
00640 #define value_minus(v1,v2) value_fake_binary(v1,v2)
00641 #undef value_pdiv
00642 #define value_pdiv(v1,v2) value_fake_binary(v1,v2)
00643 #undef value_div
00644 #define value_div(v1,v2) value_fake_binary(v1,v2)
00645 #undef value_mod
00646 #define value_mod(v1,v2) value_fake_binary(v1,v2)
00647 #undef value_addto
00648 #define value_addto(v1,v2) value_assign(v1,value_plus(v1,v2))
00649 #undef value_subtract
00650 #define value_subtract(v1,v2) value_addto(v1,v2)
00651 #undef value_product
00652 #define value_product(v1,v2) value_addto(v1,v2)
00653 #undef value_modulus
00654 #define value_modulus(v1,v2) value_addto(v1,v2)
00655 #undef value_division
00656 #define value_division(v1,v2) value_addto(v1,v2)
00657 #undef value_divexact
00658 #define value_divexact(v1,v2) value_addto(v1,v2)
00659 #undef value_increment
00660 #define value_increment(v) value_addto(v,VALUE_ONE)
00661 #undef value_decrement
00662 #define value_decrement(v) value_addto(v,VALUE_MONE)
00663 #undef value_orto
00664 #define value_orto(ref,val) value_addto(v1,v2)
00665 #undef value_andto
00666 #define value_andto(ref,val) value_addto(v1,v2) 
00667 #undef value_or
00668 #define value_or(v1,v2) value_fake_binary(v1,v2)
00669 #undef value_and
00670 #define value_and(v1,v2) value_fake_binary(v1,v2)
00671 #undef value_lshift
00672 #define value_lshift(v1,v2) value_fake_binary(v1,v2)
00673 #undef value_rshift
00674 #define value_rshift(v1,v2) value_fake_binary(v1,v2)
00675 #endif 
00676 
00677 /* for backward compatibility */
00678 #define value_substract(ref,val1,val2) (value_subtract((ref),(val1),(val2)))
00679 
00680 /* valeur absolue
00681  */
00682 #ifndef ABS
00683 #define ABS(x) (((x)>=0) ? (x) : -(x))
00684 #endif
00685 
00686 /* minimum et maximum 
00687  * if they are defined somewhere else, they are very likely 
00688  * to be defined the same way. Thus the previous def is not overwritten.
00689  */
00690 #ifndef MIN
00691 #define MIN(x,y) (((x)>=(y))?(y):(x))
00692 #endif
00693 #ifndef MAX
00694 #define MAX(x,y) (((x)>=(y))?(x):(y))
00695 #endif
00696 
00697 /* signe d'un entier: -1, 0 ou 1 */
00698 #define SIGN(x) (((x)>0)? 1 : ((x)==0? 0 : -1))
00699 
00700 /* division avec reste toujours positif
00701  * basee sur les equations:
00702  * a/(-b) = - (a/b)
00703  * (-a)/b = - ((a+b-1)/b)
00704  * ou a et b sont des entiers positifs
00705  */
00706 #define DIVIDE(x,y) ((y)>0? POSITIVE_DIVIDE(x,y) : \
00707                      -POSITIVE_DIVIDE((x),(-(y))))
00708 
00709 /* division avec reste toujours positif quand y est positif: assert(y>=0) */
00710 #define POSITIVE_DIVIDE(x,y) ((x)>0 ? (x)/(y) : - (-(x)+(y)-1)/(y))
00711 
00712 /* modulo a resultat toujours positif */
00713 #define MODULO(x,y) ((y)>0 ? POSITIVE_MODULO(x,y) : POSITIVE_MODULO(-x,-y))
00714 
00715 /* modulo par rapport a un nombre positif: assert(y>=0)
00716  *
00717  * Ce n'est pas la macro la plus efficace que j'aie jamais ecrite: il faut
00718  * faire, dans le pire des cas, deux appels a la routine .rem, qui n'est
00719  * surement pas plus cablee que la division ou la multiplication
00720  */
00721 #define POSITIVE_MODULO(x,y) ((x) > 0 ? (x)%(y) : \
00722                               ((x)%(y) == 0 ? 0 : ((y)-(-(x))%(y))))
00723                               
00724 /* errors.c */ 
00725 extern unsigned int overflow_error;
00726 extern unsigned int simplex_arithmetic_error;
00727 extern unsigned int user_exception_error;
00728 extern unsigned int parser_exception_error;
00729 extern unsigned int any_exception_error; 
00730 extern unsigned int the_last_just_thrown_exception;
00731 extern void dump_exception_stack_to_file(FILE * /*f*/);
00732 extern void dump_exception_stack(void);
00733 extern jmp_buf *push_exception_on_stack(int /*what*/, const char * /*function*/, const char * /*file*/, int /*line*/);
00734 extern void pop_exception_from_stack(int /*what*/, const char * /*function*/, const char * /*file*/, int /*line*/);
00735 extern void throw_exception(int /*what*/, const char * /*function*/, const char * /*file*/, int /*line*/);
00736 
00737 #endif /* arithmetique_header_included */
00738 
00739 
00740 

Generated on Thu Sep 4 15:28:57 2008 for polylib by doxygen 1.3.5