bool isDiv = (k == kind::INTS_DIVISION || k == kind::INTS_DIVISION_TOTAL);
- Integer result = isDiv ? ni.floorDivideQuotient(di) : ni.floorDivideRemainder(di);
+ Integer result = isDiv ? ni.euclidianDivideQuotient(di) : ni.euclidianDivideRemainder(di);
Node resultNode = mkRationalNode(Rational(result));
return RewriteResponse(REWRITE_DONE, resultNode);
DeltaRationalException::~DeltaRationalException() throw () { }
-Integer DeltaRational::floorDivideQuotient(const DeltaRational& y) const throw(DeltaRationalException){
+Integer DeltaRational::euclidianDivideQuotient(const DeltaRational& y) const throw(DeltaRationalException){
if(isIntegral() && y.isIntegral()){
Integer ti = floor();
Integer yi = y.floor();
- return ti.floorDivideQuotient(yi);
+ return ti.euclidianDivideQuotient(yi);
}else{
- throw DeltaRationalException("floorDivideQuotient", *this, y);
+ throw DeltaRationalException("euclidianDivideQuotient", *this, y);
}
}
-Integer DeltaRational::floorDivideRemainder(const DeltaRational& y) const throw(DeltaRationalException){
+Integer DeltaRational::euclidianDivideRemainder(const DeltaRational& y) const throw(DeltaRationalException){
if(isIntegral() && y.isIntegral()){
Integer ti = floor();
Integer yi = y.floor();
- return ti.floorDivideRemainder(yi);
+ return ti.euclidianDivideRemainder(yi);
}else{
- throw DeltaRationalException("floorDivideRemainder", *this, y);
+ throw DeltaRationalException("euclidianDivideRemainder", *this, y);
}
}
}
/** Only well defined if both this and y are integral. */
- Integer floorDivideQuotient(const DeltaRational& y) const throw(DeltaRationalException);
+ Integer euclidianDivideQuotient(const DeltaRational& y) const throw(DeltaRationalException);
/** Only well defined if both this and y are integral. */
- Integer floorDivideRemainder(const DeltaRational& y) const throw(DeltaRationalException);
+ Integer euclidianDivideRemainder(const DeltaRational& y) const throw(DeltaRationalException);
std::string toString() const;
if(n.getKind() == kind::DIVISION_TOTAL){
res = numer / denom;
}else if(n.getKind() == kind::INTS_DIVISION_TOTAL){
- res = Rational(numer.floorDivideQuotient(denom));
+ res = Rational(numer.euclidianDivideQuotient(denom));
}else{
Assert(n.getKind() == kind::INTS_MODULUS_TOTAL);
- res = Rational(numer.floorDivideRemainder(denom));
+ res = Rational(numer.euclidianDivideRemainder(denom));
}
if(isSetup(n)){
ArithVar var = d_arithvarNodeMap.asArithVar(n);
return Integer( cln::ceiling2(d_value, y.d_value).remainder );
}
+ /**
+ * Computes a quoitent and remainder according to Boute's Euclidean definition.
+ * euclidianDivideQuotient, euclidianDivideRemainder.
+ *
+ * Boute, Raymond T. (April 1992).
+ * The Euclidean definition of the functions div and mod.
+ * ACM Transactions on Programming Languages and Systems (TOPLAS)
+ * ACM Press. 14 (2): 127 - 144. doi:10.1145/128861.128862.
+ */
+ static void euclidianQR(Integer& q, Integer& r, const Integer& x, const Integer& y) {
+ // compute the floor and then fix the value up if needed.
+ floorQR(q,r,x,y);
+
+ if(r.strictlyNegative()){
+ // if r < 0
+ // abs(r) < abs(y)
+ // - abs(y) < r < 0, then 0 < r + abs(y) < abs(y)
+ // n = y * q + r
+ // n = y * q - abs(y) + r + abs(y)
+ if(r.sgn() >= 0){
+ // y = abs(y)
+ // n = y * q - y + r + y
+ // n = y * (q-1) + (r+y)
+ q -= 1;
+ r += y;
+ }else{
+ // y = -abs(y)
+ // n = y * q + y + r - y
+ // n = y * (q+1) + (r-y)
+ q += 1;
+ r -= y;
+ }
+ }
+ }
+
+ /**
+ * Returns the quoitent according to Boute's Euclidean definition.
+ * See the documentation for euclidianQR.
+ */
+ Integer euclidianDivideQuotient(const Integer& y) const {
+ Integer q,r;
+ euclidianQR(q,r, *this, y);
+ return q;
+ }
+
+ /**
+ * Returns the remainfing according to Boute's Euclidean definition.
+ * See the documentation for euclidianQR.
+ */
+ Integer euclidianDivideRemainder(const Integer& y) const {
+ Integer q,r;
+ euclidianQR(q,r, *this, y);
+ return r;
+ }
+
/**
* If y divides *this, then exactQuotient returns (this/y)
*/
return cln::cl_I_to_int(sgn);
}
- bool isZero() const {
- return cln::zerop(d_value);
+
+ inline bool strictlyPositive() const {
+ return sgn() > 0;
+ }
+
+ inline bool strictlyNegative() const {
+ return sgn() < 0;
+ }
+
+ inline bool isZero() const {
+ return sgn() == 0;
}
- bool isOne() const {
+ inline bool isOne() const {
return d_value == 1;
}
- bool isNegativeOne() const {
+ inline bool isNegativeOne() const {
return d_value == -1;
}
mpz_class res = d_value;
for (unsigned i = size; i < size + amount; ++i) {
- mpz_setbit(res.get_mpz_t(), i);
+ mpz_setbit(res.get_mpz_t(), i);
}
-
- return Integer(res);
+
+ return Integer(res);
}
-
+
uint32_t toUnsignedInt() const {
return mpz_get_ui(d_value.get_mpz_t());
}
-
+
/** See GMP Documentation. */
Integer extractBitRange(uint32_t bitCount, uint32_t low) const {
// bitCount = high-low+1
return Integer( r );
}
+ /**
+ * Computes a quoitent and remainder according to Boute's Euclidean definition.
+ * euclidianDivideQuotient, euclidianDivideRemainder.
+ *
+ * Boute, Raymond T. (April 1992).
+ * The Euclidean definition of the functions div and mod.
+ * ACM Transactions on Programming Languages and Systems (TOPLAS)
+ * ACM Press. 14 (2): 127 - 144. doi:10.1145/128861.128862.
+ */
+ static void euclidianQR(Integer& q, Integer& r, const Integer& x, const Integer& y) {
+ // compute the floor and then fix the value up if needed.
+ floorQR(q,r,x,y);
+
+ if(r.strictlyNegative()){
+ // if r < 0
+ // abs(r) < abs(y)
+ // - abs(y) < r < 0, then 0 < r + abs(y) < abs(y)
+ // n = y * q + r
+ // n = y * q - abs(y) + r + abs(y)
+ if(r.sgn() >= 0){
+ // y = abs(y)
+ // n = y * q - y + r + y
+ // n = y * (q-1) + (r+y)
+ q -= 1;
+ r += y;
+ }else{
+ // y = -abs(y)
+ // n = y * q + y + r - y
+ // n = y * (q+1) + (r-y)
+ q += 1;
+ r -= y;
+ }
+ }
+ }
+ /**
+ * Returns the quoitent according to Boute's Euclidean definition.
+ * See the documentation for euclidianQR.
+ */
+ Integer euclidianDivideQuotient(const Integer& y) const {
+ Integer q,r;
+ euclidianQR(q,r, *this, y);
+ return q;
+ }
+
+ /**
+ * Returns the remainfing according to Boute's Euclidean definition.
+ * See the documentation for euclidianQR.
+ */
+ Integer euclidianDivideRemainder(const Integer& y) const {
+ Integer q,r;
+ euclidianQR(q,r, *this, y);
+ return r;
+ }
+
+
/**
* If y divides *this, then exactQuotient returns (this/y)
*/
* Returns y mod 2^exp
*/
Integer modByPow2(uint32_t exp) const {
- mpz_class res;
+ mpz_class res;
mpz_fdiv_r_2exp(res.get_mpz_t(), d_value.get_mpz_t(), exp);
return Integer(res);
}
return Integer(res);
}
-
+
int sgn() const {
return mpz_sgn(d_value.get_mpz_t());
}
- bool isZero() const {
+ inline bool strictlyPositive() const {
+ return sgn() > 0;
+ }
+
+ inline bool strictlyNegative() const {
+ return sgn() < 0;
+ }
+
+ inline bool isZero() const {
return sgn() == 0;
}