00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #ifndef COUENNE_EXPRBDIV_H
00012 #define COUENNE_EXPRBDIV_H
00013
00014 #include "exprOp.hpp"
00015
00016
00018 static inline CouNumber safeDiv (register CouNumber a, register CouNumber b, int sign) {
00019
00020 if (fabs (a) < COUENNE_EPS) return 0;
00021
00022
00023
00024 if (fabs (b) < COUENNE_EPS) return ((sign < 0) ? -COUENNE_INFINITY : COUENNE_INFINITY);
00025
00026 if (a > COUENNE_INFINITY) return ((sign < 0) ? -COUENNE_INFINITY : COUENNE_INFINITY);
00027 if (a < -COUENNE_INFINITY) return ((sign < 0) ? -COUENNE_INFINITY : COUENNE_INFINITY);
00028
00029 return a/b;
00030 }
00031
00032
00035
00036 class exprLBDiv: public exprOp {
00037
00038 public:
00039
00041 exprLBDiv (expression **al, int n):
00042 exprOp (al, n) {}
00043
00045 expression *clone (Domain *d = NULL) const
00046 {return new exprLBDiv (clonearglist (d), nargs_);}
00047
00049 CouNumber operator () ();
00050
00052 enum pos printPos () const
00053 {return PRE;}
00054
00056 std::string printOp () const
00057 {return "LB_Div";}
00058 };
00059
00060
00062
00063 inline CouNumber exprLBDiv::operator () () {
00064
00065 register CouNumber n = (*(arglist_ [0])) ();
00066 register CouNumber N = (*(arglist_ [1])) ();
00067 register CouNumber d = (*(arglist_ [2])) ();
00068 register CouNumber D = (*(arglist_ [3])) ();
00069
00070 if (d > 0)
00071 if (n > 0) return safeDiv (n,D,-1);
00072 else return safeDiv (n,d,-1);
00073 else {
00074 if (D > 0) return - COUENNE_INFINITY;
00075 else if (N > 0) return safeDiv (N,D,-1);
00076 else return safeDiv (N,d,-1);
00077 }
00078 }
00079
00080
00083
00084 class exprUBDiv: public exprOp {
00085
00086 public:
00087
00089 exprUBDiv (expression **al, int n):
00090 exprOp (al, n) {}
00091
00093 expression *clone (Domain *d = NULL) const
00094 {return new exprUBDiv (clonearglist (d), nargs_);}
00095
00097 CouNumber operator () ();
00098
00100 enum pos printPos () const
00101 {return PRE;}
00102
00104 std::string printOp () const
00105 {return "UB_Div";}
00106 };
00107
00108
00110
00111 inline CouNumber exprUBDiv::operator () () {
00112
00113 register CouNumber n = (*(arglist_ [0])) ();
00114 register CouNumber N = (*(arglist_ [1])) ();
00115 register CouNumber d = (*(arglist_ [2])) ();
00116 register CouNumber D = (*(arglist_ [3])) ();
00117
00118 if (d > 0)
00119 if (N < 0) return safeDiv (N,D,1);
00120 else return safeDiv (N,d,1);
00121 else {
00122 if (D > 0) return + COUENNE_INFINITY;
00123 else if (n < 0) return safeDiv (n,D,1);
00124 else return safeDiv (n,d,1);
00125 }
00126 }
00127
00128 #endif