Example #1
0
        /** Return this raised to an integer power.
         * Implemented by repeated squaring and multiplication.
         * If y < 0, returns div_inv of the result. */
        public virtual Numeric power(IntNum y)
        {
            if (y.isNegative())
            {
                return(power(IntNum.neg(y)).div_inv());
            }
            Numeric pow2 = this;
            Numeric r    = null;

            for (;;)  // for (i = 0;  ; i++)
            {
                // pow2 == x**(2**i)
                // prod = x**(sum(j=0..i-1, (y>>j)&1))
                if (y.isOdd())
                {
                    r = r == null ? pow2 : r.mul(pow2);       // r *= pow2
                }
                y = IntNum.shift(y, -1);
                if (y.isZero())
                {
                    break;
                }
                // pow2 *= pow2;
                pow2 = pow2.mul(pow2);
            }
            return(r == null?mul_ident() : r);
        }
Example #2
0
        /** 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));
        }
Example #3
0
        public override double doubleValue()
        {
            bool neg = num.isNegative();

            if (den.isZero())
            {
                return(neg ? Double.NegativeInfinity
                        : num.isZero() ? Double.NaN
                        : Double.PositiveInfinity);
            }
            IntNum n = num;

            if (neg)
            {
                n = IntNum.neg(n);
            }
            int num_len = n.intLength();
            int den_len = den.intLength();
            int exp     = 0;

            if (num_len < den_len + 54)
            {
                exp = den_len + 54 - num_len;
                n   = IntNum.shift(n, exp);
                exp = -exp;
            }

            // Divide n (which is shifted num) by den, using truncating division,
            // and return quot and remainder.
            IntNum quot      = new IntNum();
            IntNum remainder = new IntNum();

            IntNum.divide(n, den, quot, remainder, TRUNCATE);
            quot      = quot.canonicalize();
            remainder = remainder.canonicalize();

            return(quot.roundToDouble(exp, neg, !remainder.isZero()));
        }