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.9 2005/08/02 16:13:57 verdoolaege Exp $
00008  *
00009  * Francois Irigoin, mai 1989
00010  *
00011  * Modifications
00012  *  - reprise de DIVIDE qui etait faux (Remi Triolet, Francois Irigoin, 
00013  *    april 90)
00014  *  - simplification de POSITIVE_DIVIDE par suppression d'un modulo
00015  *  - B.Meister : added addmul, operation existing in gmp and useful 
00016  *    for matrix multiplications (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 #endif 
00037 
00038 /* 
00039    #        ####   #    #   ####           #        ####   #    #   ####
00040    #       #    #  ##   #  #    #          #       #    #  ##   #  #    #
00041    #       #    #  # #  #  #               #       #    #  # #  #  #
00042    #       #    #  #  # #  #  ###          #       #    #  #  # #  #  ###
00043    #       #    #  #   ##  #    #          #       #    #  #   ##  #    #
00044    ######   ####   #    #   ####           ######   ####   #    #   ####
00045    
00046 */
00047 
00048 /* 
00049  * Constants like LONG_LONG_MAX are not defined with ansi options, so they are
00050  * defined here. 
00051  */  
00052 
00053 #ifndef LONG_LONG_MAX
00054 
00055 /* would fix on solaris:
00056  * #define LONG_LONG_MAX LLONG_MAX
00057  * #define LONG_LONG_MIN LLONG_MIN
00058  */
00059 
00060 #ifndef __LONG_LONG_MAX__
00061 #define __LONG_LONG_MAX__ 9223372036854775807LL
00062 #endif
00063 #undef LONG_LONG_MAX
00064 #define LONG_LONG_MAX __LONG_LONG_MAX__
00065 #undef LONG_LONG_MIN
00066 #define LONG_LONG_MIN (-LONG_LONG_MAX-1)
00067 #undef ULONG_LONG_MAX
00068 #define ULONG_LONG_MAX (LONG_LONG_MAX * 2ULL + 1)
00069 #endif
00070 
00071 #if defined(LINEAR_VALUE_IS_LONGLONG)
00072 
00073 #define LINEAR_VALUE_STRING "long long int"
00074 typedef long long int Value;
00075 #if defined(WIN32) && !defined(unix)
00076     /* Mingw or Windows need an incompatible format string. */
00077 #   define VALUE_FMT "%I64d"
00078 #else
00079 #   define VALUE_FMT "%lld"
00080 #endif
00081 #define VALUE_CONST(val) (val##LL) 
00082 
00083 /* 
00084  * CAUTION! 'VALUE_MIN' is defined as 'LONG_LONG_MIN +1' so as to preserve the
00085  * symmetry (-min==max) and to have a NAN value. FC 
00086  */ 
00087 
00088 #define VALUE_NAN LONG_LONG_MIN
00089 #define VALUE_MIN (LONG_LONG_MIN+1LL)
00090 #define VALUE_MAX LONG_LONG_MAX
00091 #define VALUE_SQRT_MIN long_to_value(LONG_MIN) 
00092 #define VALUE_SQRT_MAX long_to_value(LONG_MAX)
00093 #define VALUE_ZERO (0LL)
00094 #define VALUE_ONE  (1LL)
00095 #define VALUE_MONE (-1LL)
00096 
00097 #define VALUE_TO_LONG(val) \
00098     ((long)((val)>(Value)LONG_MIN&&(val)<=(Value)LONG_MAX)?\
00099      (val):(THROW(overflow_error), LONG_MIN))
00100 
00101 #define VALUE_TO_INT(val) \
00102     ((int)((val)>(Value)INT_MIN&&(val)<=(Value)INT_MAX)?\
00103      (val):(THROW(overflow_error), INT_MIN))
00104 
00105 #define VALUE_TO_DOUBLE(val) ((double)(val))
00106 
00107 /* #define VALUE_TO_FLOAT(val) ((float)(val)): Doesn't seem to work with gcc */
00108 #define VALUE_TO_FLOAT(val) ((float)((int)(val)))
00109 
00110 /* end LINEAR_VALUE_IS_LONGLONG */
00111 
00112 /* 
00113  
00114    #        ####   #    #   ####
00115    #       #    #  ##   #  #    #
00116    #       #    #  # #  #  #
00117    #       #    #  #  # #  #  ###
00118    #       #    #  #   ##  #    #
00119    ######   ####   #    #   ####
00120  
00121 */
00122 
00123 #elif defined(LINEAR_VALUE_IS_LONG)
00124 
00125 #define LINEAR_VALUE_STRING "long int"
00126 typedef long Value;
00127 #define VALUE_FMT "%ld"
00128 #define VALUE_CONST(val) (val##L)
00129 #define VALUE_NAN LONG_MIN
00130 #define VALUE_MIN (LONG_MIN+1L)
00131 #define VALUE_MAX LONG_MAX
00132 #define VALUE_ZERO 0L
00133 #define VALUE_ONE  1L
00134 #define VALUE_MONE -1L
00135 #define VALUE_TO_LONG(val) (val)
00136 #define VALUE_TO_INT(val) ((int)(val))
00137 #define VALUE_TO_FLOAT(val) ((float)(val))
00138 #define VALUE_TO_DOUBLE(val) ((double)(val))
00139 
00140 /* end LINEAR_VALUE_IS_LONG */
00141 
00142 /* 
00143    ######  #        ####     ##     #####
00144    #       #       #    #   #  #      #
00145    #####   #       #    #  #    #     #
00146    #       #       #    #  ######     #
00147    #       #       #    #  #    #     #
00148    #       ######   ####   #    #     #
00149  
00150 */
00151 
00152 /*
00153 #elif defined(LINEAR_VALUE_IS_FLOAT)
00154 
00155 #define LINEAR_VALUE_STRING "float"
00156 typedef float Value;
00157 #define VALUE_FMT "%f"
00158 #define VALUE_CONST(val) (val)
00159 #define VALUE_MIN FLOAT_MIN
00160 #define VALUE_MAX FLOAT_MAX
00161 #define VALUE_ZERO 0.0
00162 #define VALUE_ONE  1.0
00163 #define VALUE_MONE -1.0
00164 #define VALUE_TO_LONG(val) ((long)(val))
00165 #define VALUE_TO_INT(val) ((int)(val))
00166 #define VALUE_TO_FLOAT(val) ((float)(val))
00167 #define VALUE_TO_DOUBLE(val) ((double)(val))
00168 
00169 */
00170 
00171 /* end LINEAR_VALUE_IS_FLOAT */
00172 
00173 /*
00174    ####   #    #    ##    #####           #   #
00175   #    #  #    #   #  #   #    #           # #
00176   #       ######  #    #  #    #         #######
00177   #       #    #  ######  #####            # #
00178   #    #  #    #  #    #  #   #           #   #
00179    ####   #    #  #    #  #    #
00180   
00181    */
00182 
00183 /* Char version is used to detect invalid assignments */
00184 
00185 #elif defined(LINEAR_VALUE_IS_CHARS)
00186 
00187 #define LINEAR_VALUE_STRING "char"
00188 typedef union { char *s; long l; int i; float f; double d;} Value;
00189 #define VALUE_FMT "%s"
00190 #define VALUE_CONST(val) ((Value)(val))
00191 #define VALUE_NAN ((Value)(long)0xdadeebee)
00192 #define VALUE_MIN ((Value)(long)0xdeadbeef)
00193 #define VALUE_MAX ((Value)(long)0xfeedabee)
00194 #define VALUE_ZERO ((Value)0)
00195 #define VALUE_ONE  ((Value)1)
00196 #define VALUE_MONE ((Value)-1)
00197 #define VALUE_TO_LONG(val) (val.l)
00198 #define VALUE_TO_INT(val) (val.i)
00199 #define VALUE_TO_FLOAT(val) (val.f)
00200 #define VALUE_TO_DOUBLE(val) (val.d)
00201 
00202 /* end LINEAR_VALUE_IS_CHARS */
00203 
00204 /*
00205     #    #    #   #####
00206     #    ##   #     #
00207     #    # #  #     #
00208     #    #  # #     #
00209     #    #   ##     #
00210     #    #    #     #
00211 
00212 */
00213 
00214 #elif defined(LINEAR_VALUE_IS_INT)
00215 
00216 #define LINEAR_VALUE_STRING "int"
00217 typedef int Value;
00218 #define VALUE_FMT "%d"
00219 #define VALUE_CONST(val) (val)
00220 #define VALUE_NAN INT_MIN
00221 #define VALUE_MIN (INT_MIN+1)
00222 #define VALUE_MAX INT_MAX
00223 #define VALUE_ZERO  0
00224 #define VALUE_ONE   1
00225 #define VALUE_MONE -1
00226 #define VALUE_TO_LONG(val) ((long)(val))
00227 #define VALUE_TO_INT(val) ((int)(val))
00228 #define VALUE_TO_FLOAT(val) ((float)(val))
00229 #define VALUE_TO_DOUBLE(val) ((double)(val))
00230 
00231 /* end LINEAR_VALUE_IS_INT */
00232 
00233 #else  /* If defined(GNUMP) */
00234 
00235 #define LINEAR_VALUE_STRING "gmp"
00236 typedef mpz_t Value;
00237 #define VALUE_FMT "%s"
00238 
00239 /* don't use these, use value_set_si instead ! */
00240 #undef VALUE_ZERO
00241 #undef VALUE_ONE
00242 #undef VALUE_MONE
00243 #define VALUE_TO_LONG(val) (mpz_get_si(val))
00244 #define VALUE_TO_INT(val) ((int)mpz_get_si(val))
00245 #define VALUE_TO_FLOAT(val) ((float)((int)mpz_get_si(val)))
00246 #define VALUE_TO_DOUBLE(val) (mpz_get_d(val))
00247 
00248 #endif 
00249 
00250 /* ***************** MACROS FOR MANIPULATING VALUES ******************** */
00251 
00252 #if defined(GNUMP)
00253 
00254 /* Basic macros */
00255 
00256 #define value_init(val)        (mpz_init((val)))
00257 #define value_assign(v1,v2)    (mpz_set((v1),(v2)))
00258 #define value_set_si(val,i)    (mpz_set_si((val),(i)))    
00259 #define value_set_double(val,d)(mpz_set_d((val),(d)))
00260 #define value_clear(val)       (mpz_clear((val)))
00261 #define value_read(val,str)    (mpz_set_str((val),(str),10))
00262 #define value_print(Dst,fmt,val)  {char *str; str = mpz_get_str(0,10,(val)); \
00263                                fprintf((Dst),(fmt),str); free(str); \
00264                               }
00265 #define value_swap(val1,val2)  {mpz_t tmp; mpz_init_set(tmp,(val1)); \
00266                                 mpz_set((val1),(val2)); mpz_set((val2),tmp); \
00267                                 mpz_clear(tmp); \
00268                                }
00269                                              
00270 /* Boolean operators on 'Value' */
00271 
00272 #define value_eq(v1,v2) (mpz_cmp((v1),(v2)) == 0)
00273 #define value_ne(v1,v2) (mpz_cmp((v1),(v2)) != 0)
00274 #define value_gt(v1,v2) (mpz_cmp((v1),(v2))  > 0)
00275 #define value_ge(v1,v2) (mpz_cmp((v1),(v2)) >= 0)
00276 #define value_lt(v1,v2) (mpz_cmp((v1),(v2))  < 0)
00277 #define value_le(v1,v2) (mpz_cmp((v1),(v2)) <= 0)
00278 
00279 /* Trian operators on 'Value' */
00280 
00281 #define value_sign(val)      (mpz_sgn(val))
00282 #define value_compare(v1,v2) (mpz_cmp((v1),(v2)))
00283 
00284 /* Binary operations on 'Value' */
00285 
00286 #define value_addto(ref,val1,val2)     (mpz_add((ref),(val1),(val2)))
00287 #define value_add_int(ref,val,vint)     (mpz_add_ui((ref),(val),(long)(vint)))
00288 #define value_addmul(ref, val1, val2)   (mpz_addmul((ref), (val1), (val2)))
00289 #define value_increment(ref,val)       (mpz_add_ui((ref),(val),1))
00290 #define value_multiply(ref,val1,val2)  (mpz_mul((ref),(val1),(val2)))
00291 #define value_subtract(ref,val1,val2) (mpz_sub((ref),(val1),(val2)))
00292 #define value_sub_int(ref,val,vint)     (mpz_sub_ui((ref),(val),(long)(vint)))
00293 #define value_decrement(ref,val)       (mpz_sub_ui((ref),(val),1))
00294 #define value_division(ref,val1,val2)  (mpz_tdiv_q((ref),(val1),(val2)))
00295 #define value_modulus(ref,val1,val2)   (mpz_tdiv_r((ref),(val1),(val2)))
00296 #define value_pdivision(ref,val1,val2) (mpz_fdiv_q((ref),(val1),(val2)))
00297 #define value_pmodulus(ref,val1,val2)  (mpz_fdiv_r((ref),(val1),(val2)))
00298 #define value_oppose(ref,val)          (mpz_neg((ref),(val)))
00299 #define value_absolute(ref,val)        (mpz_abs((ref),(val)))
00300 #define value_minimum(ref,val1,val2)   (value_le((val1),(val2)) ?  \
00301                                         mpz_set((ref),(val1)) :    \
00302                                         mpz_set((ref),(val2)))  
00303 #define value_maximum(ref,val1,val2)   (value_ge((val1),(val2)) ?  \
00304                                         mpz_set((ref),(val1)) :    \
00305                                         mpz_set((ref),(val2)))  
00306 #define value_orto(ref,val1,val2)      (mpz_ior((ref),(val1),(val2)))
00307 #define value_andto(ref,val1,val2)     (mpz_and((ref),(val1),(val2)))
00308 
00309 /* Conditional operations on 'Value' */
00310 
00311 #define value_pos_p(val)         (mpz_sgn(val) >  0)
00312 #define value_neg_p(val)         (mpz_sgn(val) <  0)
00313 #define value_posz_p(val)        (mpz_sgn(val) >= 0)
00314 #define value_negz_p(val)        (mpz_sgn(val) <= 0)
00315 #define value_zero_p(val)        (mpz_sgn(val) == 0)
00316 #define value_notzero_p(val)     (mpz_sgn(val) != 0)
00317 #define value_one_p(val)         (mpz_cmp_si(val,1) == 0)
00318 #define value_notone_p(val)      (mpz_cmp_si(val,1) != 0)
00319 #define value_mone_p(val)        (mpz_cmp_si(val,-1) ==0)
00320 #define value_notmone_p(val)     (mpz_cmp_si(val,-1) !=0)
00321 #define value_cmp_si(val, n)     (mpz_cmp_si(val,n))
00322 
00323 /* ************************************************************************* */
00324 
00325 #else /* 'Value' set to longlong|long|float|char *|int */                                       
00326 /* Basic Macros */                                  
00327 
00328 #define value_init(val)            ((val) = 0)
00329 #define value_assign(v1,v2)        ((v1)  = (v2))
00330 #define value_set_si(val,i)        ((val) = (Value)(i))   
00331 #define value_set_double(val,d)    ((val) = (Value)(d)) 
00332 #define value_clear(val)           ((val) = 0)
00333 #define value_read(val,str)        (sscanf((str),VALUE_FMT,&(val)))
00334 #define value_print(Dst,fmt,val)   (fprintf((Dst),(fmt),(val)))
00335 #define value_swap(v1,v2)          {Value tmp; tmp = v2; \
00336                                     v2 = v1; v1 = tmp;   \
00337                                    }
00338 /* Cast to 'Value' */
00339 
00340 #define int_to_value(i) ((Value)(i))
00341 #define long_to_value(l) ((Value)(l))
00342 #define float_to_value(f) ((Value)(f))
00343 #define double_to_value(d) ((Value)(d))
00344    
00345 /* Boolean operators on 'Value' */
00346 
00347 #define value_eq(v1,v2) ((v1)==(v2))
00348 #define value_ne(v1,v2) ((v1)!=(v2))
00349 #define value_gt(v1,v2) ((v1)>(v2))
00350 #define value_ge(v1,v2) ((v1)>=(v2))
00351 #define value_lt(v1,v2) ((v1)<(v2))
00352 #define value_le(v1,v2) ((v1)<=(v2))
00353 
00354 /* Trian operators on 'Value' */
00355 
00356 #define value_sign(v) (value_eq(v,VALUE_ZERO)?0:value_lt(v,VALUE_ZERO)?-1:1)
00357 #define value_compare(v1,v2) (value_eq(v1,v2)?0:value_lt(v1,v2)?-1:1)
00358 
00359 /* Binary operators on 'Value' */
00360 
00361 #define value_plus(v1,v2)               ((v1)+(v2))
00362 #define value_div(v1,v2)                ((v1)/(v2))
00363 #define value_mod(v1,v2)                ((v1)%(v2))
00364 #define value_direct_multiply(v1,v2)    ((v1)*(v2)) /* direct! */
00365 #define value_minus(v1,v2)              ((v1)-(v2))
00366 #define value_pdiv(v1,v2)               (divide((v1),(v2)))
00367 #define value_pmod(v1,v2)               (modulo((v1),(v2)))
00368 #define value_min(v1,v2)                (value_le((v1),(v2))? (v1): (v2))
00369 #define value_max(v1,v2)                (value_ge((v1),(v2))? (v1): (v2))
00370 #define value_or(v1,v2)                 ((v1)|(v2))
00371 #define value_and(v1,v2)                ((v1)&(v2))
00372 #define value_lshift(v1,v2)             ((v1)<<(v2))
00373 #define value_rshift(v1,v2)             ((v1)>>(v2))
00374                                   
00375 /* Binary operations on 'Value' */ 
00376 
00377 #define value_addto(ref,val1,val2)      ((ref) = (val1)+(val2))
00378 #define value_add_int(ref,val,vint)     ((ref) = (val)+(Value)(vint))
00379 #define value_addmul(ref, val1, val2)   ((ref) += (val1)*(val2))
00380 #define value_increment(ref,val)        ((ref) = (val)+VALUE_ONE)
00381 #define value_direct_product(ref,val1,val2) ((ref) = (val1)*(val2)) /* direct! */
00382 #define value_multiply(ref,val1,val2)   ((ref) = value_mult((val1),(val2)))
00383 #define value_subtract(ref,val1,val2)   ((ref) = (val1)-(val2))
00384 #define value_sub_int(ref,val,vint)     ((ref) = (val)-(Value)(vint))
00385 #define value_decrement(ref,val)        ((ref) = (val)-VALUE_ONE)
00386 #define value_division(ref,val1,val2)   ((ref) = (val1)/(val2))
00387 #define value_modulus(ref,val1,val2)    ((ref) = (val1)%(val2))
00388 #define value_pdivision(ref,val1,val2)  ((ref) = value_pdiv((val1),(val2)))
00389 #define value_pmodulus(ref,val1,val2)   ((ref) = value_pmod((val1),(val2)))
00390 #define value_oppose(ref,val)           ((ref) = value_uminus((val)))
00391 #define value_absolute(ref,val)         ((ref) = value_abs((val)))
00392 #define value_minimum(ref,val1,val2)    ((ref) = value_min((val1),(val2)))
00393 #define value_maximum(ref,val1,val2)    ((ref) = value_max((val1),(val2)))
00394 #define value_orto(ref,val1,val2)       ((ref) = (val1)|(val2))
00395 #define value_andto(ref,val1,val2)      ((ref) = (val1)&(val2))
00396 
00397 /* Unary operators on 'Value' */
00398 
00399 #define value_uminus(val)  (-(val))
00400 #define value_not(val)  (~(val))
00401 #define value_abs(val) (value_posz_p(val)? \
00402     (val) :                                \
00403     (value_ne((val), VALUE_NAN) ?          \
00404      value_uminus(val) :                   \
00405     (THROW (overflow_error), VALUE_NAN )))
00406 
00407 /* Conditional operations on 'Value' */
00408 
00409 #define value_pos_p(val)      value_gt(val,VALUE_ZERO)
00410 #define value_neg_p(val)      value_lt(val,VALUE_ZERO)
00411 #define value_posz_p(val)     value_ge(val,VALUE_ZERO)
00412 #define value_negz_p(val)     value_le(val,VALUE_ZERO)
00413 #define value_zero_p(val)     value_eq(val,VALUE_ZERO)
00414 #define value_notzero_p(val)  value_ne(val,VALUE_ZERO)
00415 #define value_one_p(val)      value_eq(val,VALUE_ONE)
00416 #define value_notone_p(val)   value_ne(val,VALUE_ONE)
00417 #define value_mone_p(val)     value_eq(val,VALUE_MONE)
00418 #define value_notmone_p(val)  value_ne(val,VALUE_MONE)
00419 #define value_cmp_si(val, n)  (val - VALUE_CONST(n))
00420 #define value_min_p(val)      value_eq(val,VALUE_MIN)
00421 #define value_max_p(val)      value_eq(val,VALUE_MAX)
00422 #define value_notmin_p(val)   value_ne(val,VALUE_MIN)
00423 #define value_notmax_p(val)   value_ne(val,VALUE_MAX)
00424 
00425 #endif /* 'Value' set to |longlong|long|float|char *|int */
00426 
00427 
00428 /* *********************** PROTECTED MULTIPLICATION ********************** */
00429 
00430 #include "arithmetic_errors.h"
00431 
00432 /* (|v| < MAX / |w|) => v*w is okay
00433  * I could check ((v*w)/w)==v but a tmp would be useful
00434  */
00435 #define value_protected_hard_idiv_multiply(v,w,throw)           \
00436   ((value_zero_p(w) || value_zero_p(v))? VALUE_ZERO:            \
00437    value_lt(value_abs(v),value_div(VALUE_MAX,value_abs(w)))?    \
00438    value_direct_multiply(v,w): (throw, VALUE_NAN))
00439 
00440 /* is a software idiv is assumed, quick check performed first
00441  */
00442 #if defined(LINEAR_VALUE_ASSUME_SOFTWARE_IDIV)
00443 #define value_protected_multiply(v,w,throw)                                   \
00444   ((value_le(v,VALUE_SQRT_MAX) && value_le(w,VALUE_SQRT_MAX) &&               \
00445    value_ge(v,VALUE_SQRT_MIN) && value_ge(w,VALUE_SQRT_MIN))?                 \
00446    value_direct_multiply(v,w): value_protected_hard_idiv_multiply(v,w,throw))
00447 #else
00448 #define value_protected_multiply(v,w,throw)             \
00449    value_protected_hard_idiv_multiply(v,w,throw)
00450 #endif
00451 
00452 /* protected versions
00453  */
00454 #define value_protected_mult(v,w)                               \
00455     value_protected_multiply(v,w,THROW(overflow_error))
00456 #define value_protected_product(v,w)            \
00457     v=value_protected_mult(v,w)
00458 
00459 /* whether the default is protected or not 
00460  * this define makes no sense any more... well, doesn't matter. FC.
00461  */
00462 #if defined(LINEAR_VALUE_PROTECT_MULTIPLY)
00463 #define value_mult(v,w) value_protected_mult(v,w)
00464 #define value_product(v,w) value_protected_product(v,w)
00465 #else
00466 
00467 /* I do enforce the protection whatever requested:-)
00468  * prints out a message and throws the exception, hoping
00469  * that some valid CATCH waits for it upwards. 
00470  */
00471 #define value_mult(v,w)                                                       \
00472   value_protected_multiply(v,w,                                               \
00473     (fprintf(stderr,"[value_mult] value overflow!\n"),THROW(overflow_error)))
00474 #define value_product(v,w) v=value_mult(v,w)
00475 
00476 /* was:
00477  * #define value_mult(v,w) value_direct_multiply(v,w)
00478  * #define value_product(v,w) value_direct_product(v,w)
00479  * could be: protected versions...
00480  */
00481 #endif
00482 
00483 /******************************************************* STATIC VALUE DEBUG */
00484 
00485 /* LINEAR_VALUE_IS_CHARS is used for type checking.
00486  * some operations are not allowed on (char*), thus
00487  * they are switched to some other operation here...
00488  */
00489 #if defined(LINEAR_VALUE_IS_CHARS)
00490 #define value_fake_binary(v1,v2) ((Value)((v1).i+(v2).i))
00491 #define value_bool_binary(v1,v2) ((int)((v1).i+(v2).i))
00492 #undef float_to_value
00493 #define float_to_value(f) ((Value)f)
00494 #undef double_to_value
00495 #define double_to_value(f) ((Value)f)
00496 #undef value_uminus
00497 #define value_uminus(v) (v)
00498 #undef value_mult
00499 #define value_mult(v1,v2) value_fake_binary(v1,v2)
00500 #undef value_mod
00501 #define value_mod(v1,v2) value_fake_binary(v1,v2)
00502 #undef value_ge
00503 #define value_ge(v1,v2) value_bool_binary(v1,v2)
00504 #undef value_gt
00505 #define value_gt(v1,v2) value_bool_binary(v1,v2)
00506 #undef value_le
00507 #define value_le(v1,v2) value_bool_binary(v1,v2)
00508 #undef value_lt
00509 #define value_lt(v1,v2) value_bool_binary(v1,v2)
00510 #undef value_ne
00511 #define value_ne(v1,v2) value_bool_binary(v1,v2)
00512 #undef value_eq
00513 #define value_eq(v1,v2) value_bool_binary(v1,v2)
00514 #undef value_plus
00515 #define value_plus(v1,v2) value_fake_binary(v1,v2)
00516 #undef value_minus
00517 #define value_minus(v1,v2) value_fake_binary(v1,v2)
00518 #undef value_pdiv
00519 #define value_pdiv(v1,v2) value_fake_binary(v1,v2)
00520 #undef value_div
00521 #define value_div(v1,v2) value_fake_binary(v1,v2)
00522 #undef value_mod
00523 #define value_mod(v1,v2) value_fake_binary(v1,v2)
00524 #undef value_addto
00525 #define value_addto(v1,v2) value_assign(v1,value_plus(v1,v2))
00526 #undef value_subtract
00527 #define value_subtract(v1,v2) value_addto(v1,v2)
00528 #undef value_product
00529 #define value_product(v1,v2) value_addto(v1,v2)
00530 #undef value_modulus
00531 #define value_modulus(v1,v2) value_addto(v1,v2)
00532 #undef value_division
00533 #define value_division(v1,v2) value_addto(v1,v2)
00534 #undef value_increment
00535 #define value_increment(v) value_addto(v,VALUE_ONE)
00536 #undef value_decrement
00537 #define value_decrement(v) value_addto(v,VALUE_MONE)
00538 #undef value_orto
00539 #define value_orto(ref,val) value_addto(v1,v2)
00540 #undef value_andto
00541 #define value_andto(ref,val) value_addto(v1,v2) 
00542 #undef value_or
00543 #define value_or(v1,v2) value_fake_binary(v1,v2)
00544 #undef value_and
00545 #define value_and(v1,v2) value_fake_binary(v1,v2)
00546 #undef value_lshift
00547 #define value_lshift(v1,v2) value_fake_binary(v1,v2)
00548 #undef value_rshift
00549 #define value_rshift(v1,v2) value_fake_binary(v1,v2)
00550 #endif 
00551 
00552 /* for backward compatibility */
00553 #define value_substract(ref,val1,val2) (value_subtract((ref),(val1),(val2)))
00554 
00555 /* valeur absolue
00556  */
00557 #ifndef ABS
00558 #define ABS(x) (((x)>=0) ? (x) : -(x))
00559 #endif
00560 
00561 /* minimum et maximum 
00562  * if they are defined somewhere else, they are very likely 
00563  * to be defined the same way. Thus the previous def is not overwritten.
00564  */
00565 #ifndef MIN
00566 #define MIN(x,y) (((x)>=(y))?(y):(x))
00567 #endif
00568 #ifndef MAX
00569 #define MAX(x,y) (((x)>=(y))?(x):(y))
00570 #endif
00571 
00572 /* signe d'un entier: -1, 0 ou 1 */
00573 #define SIGN(x) (((x)>0)? 1 : ((x)==0? 0 : -1))
00574 
00575 /* division avec reste toujours positif
00576  * basee sur les equations:
00577  * a/(-b) = - (a/b)
00578  * (-a)/b = - ((a+b-1)/b)
00579  * ou a et b sont des entiers positifs
00580  */
00581 #define DIVIDE(x,y) ((y)>0? POSITIVE_DIVIDE(x,y) : \
00582                      -POSITIVE_DIVIDE((x),(-(y))))
00583 
00584 /* division avec reste toujours positif quand y est positif: assert(y>=0) */
00585 #define POSITIVE_DIVIDE(x,y) ((x)>0 ? (x)/(y) : - (-(x)+(y)-1)/(y))
00586 
00587 /* modulo a resultat toujours positif */
00588 #define MODULO(x,y) ((y)>0 ? POSITIVE_MODULO(x,y) : POSITIVE_MODULO(-x,-y))
00589 
00590 /* modulo par rapport a un nombre positif: assert(y>=0)
00591  *
00592  * Ce n'est pas la macro la plus efficace que j'aie jamais ecrite: il faut
00593  * faire, dans le pire des cas, deux appels a la routine .rem, qui n'est
00594  * surement pas plus cablee que la division ou la multiplication
00595  */
00596 #define POSITIVE_MODULO(x,y) ((x) > 0 ? (x)%(y) : \
00597                               ((x)%(y) == 0 ? 0 : ((y)-(-(x))%(y))))
00598                               
00599 /* Pour la recherche de performance, selection d'une implementation
00600  * particuliere des fonctions
00601  */
00602 
00603 #define divide(a,b) DIVIDE(a,b)
00604 
00605 #define modulo(a,b) MODULO(a,b)
00606 
00607 typedef struct {Value num, den; int numero ; } frac ;
00608 typedef struct col{int taille, existe ; frac *colonne ;} tableau ;
00609 
00610 /* errors.c */ 
00611 extern unsigned int overflow_error;
00612 extern unsigned int simplex_arithmetic_error;
00613 extern unsigned int user_exception_error;
00614 extern unsigned int parser_exception_error;
00615 extern unsigned int any_exception_error; 
00616 extern unsigned int the_last_just_thrown_exception;
00617 extern int linear_exception_debug_mode;
00618 extern void dump_exception_stack_to_file(FILE * /*f*/);
00619 extern void dump_exception_stack(void);
00620 extern jmp_buf *push_exception_on_stack(int /*what*/, char * /*function*/, char * /*file*/, int /*line*/);
00621 extern void pop_exception_from_stack(int /*what*/, char * /*function*/, char * /*file*/, int /*line*/);
00622 extern void throw_exception(int /*what*/, const char * /*function*/, const char * /*file*/, int /*line*/);
00623 
00624 #endif /* arithmetique_header_included */
00625 
00626 
00627 

Generated on Mon Sep 12 15:15:10 2005 for polylib by doxygen 1.3.5