Beispiel #1
0
        public static object Power([NotNull] BigInteger x, [NotNull] BigInteger y)
        {
            int  yl;
            long y2;

            if (y.AsInt32(out yl))
            {
                return(Power(x, yl));
            }
            else if (y.AsInt64(out y2))
            {
                return(Power(x, y2));
            }
            else
            {
                if (x == BigInteger.Zero)
                {
                    if (y.Sign < 0)
                    {
                        throw PythonOps.ZeroDivisionError("0.0 cannot be raised to a negative power");
                    }
                    return(BigInteger.Zero);
                }
                else if (x == BigInteger.One)
                {
                    return(BigInteger.One);
                }
                else
                {
                    throw PythonOps.ValueError("Number too big");
                }
            }
        }
 public static Single FloorDivide(Single x, Single y)
 {
     if (y == 0)
     {
         throw PythonOps.ZeroDivisionError();
     }
     return((Single)Math.Floor(x / y));
 }
 public static Single TrueDivide(Single x, Single y)
 {
     if (y == 0)
     {
         throw PythonOps.ZeroDivisionError();
     }
     return(x / y);
 }
Beispiel #4
0
        public static object Power(BigInteger x, BigInteger y, BigInteger z) {
            if (y < BigInteger.Zero) {
                throw PythonOps.TypeError("power", y, "power must be >= 0");
            }
            if (z == BigInteger.Zero) {
                throw PythonOps.ZeroDivisionError();
            }

            BigInteger result = x.ModPow(y, z);

            // fix the sign for negative moduli or negative mantissas
            if ((z < BigInteger.Zero && result > BigInteger.Zero)
                || (z > BigInteger.Zero && result < BigInteger.Zero)) {
                result += z;
            }
            return result;
        }
Beispiel #5
0
        public static double Power(double x, double y)
        {
            if (x == 0.0 && y < 0.0)
            {
                throw PythonOps.ZeroDivisionError("0.0 cannot be raised to a negative power");
            }
            if (x < 0 && (Math.Floor(y) != y))
            {
                throw PythonOps.ValueError("negative number cannot be raised to fraction");
            }
            double result = Math.Pow(x, y);

            if (double.IsInfinity(result))
            {
                throw PythonOps.OverflowError("result too large");
            }
            return(result);
        }
Beispiel #6
0
        public static double Mod(double x, double y)
        {
            if (y == 0)
            {
                throw PythonOps.ZeroDivisionError();
            }

            double r = x % y;

            if (r > 0 && y < 0)
            {
                r = r + y;
            }
            else if (r < 0 && y > 0)
            {
                r = r + y;
            }
            return(r);
        }
Beispiel #7
0
        public static Complex op_Power(Complex x, Complex y)
        {
            if (x.IsZero())
            {
                if (y.Real < 0.0 || y.Imaginary() != 0.0)
                {
                    throw PythonOps.ZeroDivisionError("0.0 to a negative or complex power");
                }
                return(y.IsZero() ? Complex.One : Complex.Zero);
            }

#if FEATURE_NUMERICS
            // Special case for higher precision with real integer powers
            // TODO: A similar check may get added to CLR 4 upon resolution of Dev10 bug 863171,
            // in which case this code should go away.
            if (y.Imaginary == 0.0)
            {
                int power = (int)y.Real;
                if (power >= 0 && y.Real == power)
                {
                    Complex res = Complex.One;
                    if (power == 0)
                    {
                        return(res);
                    }
                    Complex factor = x;
                    while (power != 0)
                    {
                        if ((power & 1) != 0)
                        {
                            res = res * factor;
                        }
                        factor  = factor * factor;
                        power >>= 1;
                    }
                    return(res);
                }
            }
#endif

            return(x.Pow(y));
        }
Beispiel #8
0
        public static object Power(int x, int power)
        {
            if (power == 0)
            {
                return(1);
            }
            if (power < 0)
            {
                if (x == 0)
                {
                    throw PythonOps.ZeroDivisionError("0.0 cannot be raised to a negative power");
                }
                return(DoubleOps.Power(x, power));
            }
            int factor    = x;
            int result    = 1;
            int savePower = power;

            try {
                checked {
                    while (power != 0)
                    {
                        if ((power & 1) != 0)
                        {
                            result = result * factor;
                        }
                        if (power == 1)
                        {
                            break;             // prevent overflow
                        }
                        factor  = factor * factor;
                        power >>= 1;
                    }
                    return(result);
                }
            } catch (OverflowException) {
                return(BigIntegerOps.Power((BigInteger)x, savePower));
            }
        }
Beispiel #9
0
        public static object Power(int x, int power, int?qmod)
        {
            if (qmod == null)
            {
                return(Power(x, power));
            }
            int mod = (int)qmod;

            if (power < 0)
            {
                throw PythonOps.TypeError("power", power, "power must be >= 0");
            }

            if (mod == 0)
            {
                throw PythonOps.ZeroDivisionError();
            }

            // This is "exponentiation by squaring" (described in Applied Cryptography; a log-time algorithm)
            long result = 1 % mod; // Handle special case of power=0, mod=1
            long factor = x;

            while (power != 0)
            {
                if ((power & 1) != 0)
                {
                    result = (result * factor) % mod;
                }
                factor  = (factor * factor) % mod;
                power >>= 1;
            }

            // fix the sign for negative moduli or negative mantissas
            if ((mod < 0 && result > 0) || (mod > 0 && result < 0))
            {
                result += mod;
            }
            return((int)result);
        }
Beispiel #10
0
        public static object DivMod(double x, double y)
        {
            if (y == 0)
            {
                throw PythonOps.ZeroDivisionError();
            }

            // .NET does not provide Math.DivRem() for floats. Implementation along the CPython code.
            var mod = Math.IEEERemainder(x, y);
            var div = (x - mod) / y;

            if (mod != 0)
            {
                if ((y < 0) != (mod < 0))
                {
                    mod += y;
                    div -= 1;
                }
            }
            else
            {
                mod = CopySign(0, y);
            }
            double floordiv;

            if (div != 0)
            {
                floordiv = Math.Floor(div);
                if (div - floordiv > 0.5)
                {
                    floordiv += 1;
                }
            }
            else
            {
                floordiv = CopySign(0, x / y);
            }
            return(PythonTuple.MakeTuple(floordiv, mod));
        }
Beispiel #11
0
        public static double Mod(double x, double y)
        {
            if (y == 0)
            {
                throw PythonOps.ZeroDivisionError();
            }

            // implemented as in CPython
            var mod = Math.IEEERemainder(x, y);

            if (mod != 0)
            {
                if ((y < 0) != (mod < 0))
                {
                    mod += y;
                }
            }
            else
            {
                mod = CopySign(0, y);
            }
            return(mod);
        }
Beispiel #12
0
        public static double Power(double x, double y)
        {
            if (x == 1.0 || y == 0.0)
            {
                return(1.0);
            }
            else if (double.IsNaN(x) || double.IsNaN(y))
            {
                return(double.NaN);
            }
            else if (x == 0.0)
            {
                if (y > 0.0)
                {
                    // preserve sign if y is a positive, odd int
                    if (y % 2.0 == 1.0)
                    {
                        return(x);
                    }
                    return(0.0);
                }
                else if (y == 0.0)
                {
                    return(1.0);
                }
                else if (double.IsNegativeInfinity(y))
                {
                    return(double.PositiveInfinity);
                }
                throw PythonOps.ZeroDivisionError("0.0 cannot be raised to a negative power");
            }
            else if (double.IsPositiveInfinity(y))
            {
                if (x > 1.0 || x < -1.0)
                {
                    return(double.PositiveInfinity);
                }
                else if (x == -1.0)
                {
                    return(1.0);
                }
                return(0.0);
            }
            else if (double.IsNegativeInfinity(y))
            {
                if (x > 1.0 || x < -1.0)
                {
                    return(0.0);
                }
                else if (x == -1.0)
                {
                    return(1.0);
                }
                return(double.PositiveInfinity);
            }
            else if (double.IsNegativeInfinity(x))
            {
                // preserve negative sign if y is an odd int
                if (Math.Abs(y % 2.0) == 1.0)
                {
                    return(y > 0 ? double.NegativeInfinity : NegativeZero);
                }
                else
                {
                    return(y > 0 ? double.PositiveInfinity : 0.0);
                }
            }
            else if (x < 0 && (Math.Floor(y) != y))
            {
                throw PythonOps.ValueError("negative number cannot be raised to fraction");
            }

            return(PythonOps.CheckMath(x, y, Math.Pow(x, y)));
        }