/** Calcaulte the simplest rational between two reals. */ public static RealNum rationalize(RealNum x, RealNum y) { // This algorithm is by Alan Bawden. It has been transcribed // with permission from C-Gambit, copyright Marc Feeley. if (x.grt(y)) { return(simplest_rational2(y, x)); } else if (!(y.grt(x))) { return(x); } else if (x.sign() > 0) { return(simplest_rational2(x, y)); } else if (y.isNegative()) { return((RealNum)(simplest_rational2((RealNum)y.neg(), (RealNum)x.neg())).neg()); } else { return(IntNum.zero()); } }
/** Converts an integral double (such as a toInt result) to an IntNum. */ public static IntNum toExactInt(double value) { if (Double.IsInfinity(value) || Double.IsNaN(value)) { throw new ArithmeticException("cannot convert " + value + " to exact integer"); } long bits = BitConverter.DoubleToInt64Bits(value); bool neg = bits < 0; int exp = (int)(bits >> 52) & 0x7FF; bits &= 0xfffffffffffffL; if (exp == 0) { bits <<= 1; } else { bits |= 0x10000000000000L; } if (exp <= 1075) { int rshift = 1075 - exp; if (rshift > 53) { return(IntNum.zero()); } bits >>= rshift; return(IntNum.make(neg ? -bits : bits)); } return(IntNum.shift(IntNum.make(neg ? -bits : bits), exp - 1075)); }
/** Do one the the 16 possible bit-wise operations of two IntNums. */ public static IntNum bitOp(int op, IntNum x, IntNum y) { switch (op) { case 0: return(IntNum.zero()); case 1: return(and(x, y)); case 3: return(x); case 5: return(y); case 15: return(IntNum.minusOne()); } IntNum result = new IntNum(); setBitOp(result, op, x, y); return(result.canonicalize()); }
/** Return the logical (bit-wise) negation of an IntNum. */ public static IntNum not(IntNum x) { return(bitOp(12, x, IntNum.zero())); }
/** Return exact "rational" infinity. * @param sign either 1 or -1 for positive or negative infinity */ public static RatNum infinity(int sign) { return(new IntFraction(IntNum.make(sign), IntNum.zero())); }
public override RealNum im() { return(IntNum.zero()); }