// Unifies the MakeFixRat logic and tries to avoid a huge computation // that will just be rounded away. // Invariant: pow >= 0 static Variable RatPow(Compartment s, BigInteger num, BigInteger den, BigInteger pow) { if (den == -BigInteger.One) { den = BigInteger.One; num = -num; } if (den == BigInteger.One) { // den won't be getting any bigger return s.MakeFixRat(big_pow(num, pow), 1); } // den >= 2 if (pow >= 64) { // Overflow is inevitable. return s.MakeFloat(Math.Pow(RatToFloat(num, den), (double)pow)); } // we might consider detecting smaller overflows, but the penalty // of $int ** 63 is not _that_ huge. return s.MakeFixRat(big_pow(num, pow), big_pow(den, pow)); }