예제 #1
0
        private static JsValue Cbrt(JsValue thisObject, JsValue[] arguments)
        {
            var x = TypeConverter.ToNumber(arguments.At(0));

            if (double.IsNaN(x))
            {
                return(JsNumber.DoubleNaN);
            }
            else if (NumberInstance.IsPositiveZero(x) || NumberInstance.IsNegativeZero(x))
            {
                return(x);
            }
            else if (double.IsPositiveInfinity(x))
            {
                return(JsNumber.DoublePositiveInfinity);
            }
            else if (double.IsNegativeInfinity(x))
            {
                return(JsNumber.DoubleNegativeInfinity);
            }

            if (System.Math.Sign(x) >= 0)
            {
                return(System.Math.Pow(x, 1.0 / 3.0));
            }

            return(-1 * System.Math.Pow(System.Math.Abs(x), 1.0 / 3.0));
        }
예제 #2
0
        private static JsValue Min(JsValue thisObject, JsValue[] arguments)
        {
            if (arguments.Length == 0)
            {
                return(JsNumber.DoublePositiveInfinity);
            }

            double min = TypeConverter.ToNumber(arguments.At(0));

            for (int i = 0; i < arguments.Length; i++)
            {
                var value = TypeConverter.ToNumber(arguments[i]);
                if (min == 0 && value == 0)
                {
                    min = NumberInstance.IsNegativeZero(min)
                        ? min
                        : value;
                }
                else
                {
                    min = System.Math.Min(min, value);
                }
            }
            return(min);
        }
예제 #3
0
        /// <summary>
        /// https://tc39.es/ecma262/#sec-math.min
        /// </summary>
        private static JsValue Min(JsValue thisObject, JsValue[] arguments)
        {
            if (arguments.Length == 0)
            {
                return(JsNumber.DoublePositiveInfinity);
            }

            var lowest = double.PositiveInfinity;

            foreach (var number in Coerced(arguments))
            {
                if (double.IsNaN(number))
                {
                    return(JsNumber.DoubleNaN);
                }

                if (NumberInstance.IsNegativeZero(number) && NumberInstance.IsPositiveZero(lowest))
                {
                    lowest = JsNumber.NegativeZero._value;
                }

                if (number < lowest)
                {
                    lowest = number;
                }
            }

            return(lowest);
        }
예제 #4
0
        private static JsValue Ceil(JsValue thisObject, JsValue[] arguments)
        {
            var x = TypeConverter.ToNumber(arguments.At(0));

            if (double.IsNaN(x))
            {
                return(double.NaN);
            }
            else if (NumberInstance.IsPositiveZero(x))
            {
                return(+0);
            }
            else if (NumberInstance.IsNegativeZero(x))
            {
                return(-0);
            }
            else if (double.IsPositiveInfinity(x))
            {
                return(double.PositiveInfinity);
            }
            else if (double.IsNegativeInfinity(x))
            {
                return(double.NegativeInfinity);
            }

            return(System.Math.Ceiling(x));
        }
예제 #5
0
        private static JsValue Floor(JsValue thisObject, JsValue[] arguments)
        {
            var x = TypeConverter.ToNumber(arguments.At(0));

            if (double.IsNaN(x))
            {
                return(JsNumber.DoubleNaN);
            }
            else if (NumberInstance.IsPositiveZero(x))
            {
                return(JsNumber.PositiveZero);
            }
            else if (NumberInstance.IsNegativeZero(x))
            {
                return(JsNumber.NegativeZero);
            }
            else if (double.IsPositiveInfinity(x))
            {
                return(JsNumber.DoublePositiveInfinity);
            }
            else if (double.IsNegativeInfinity(x))
            {
                return(JsNumber.DoubleNegativeInfinity);
            }

            return(System.Math.Floor(x));
        }
예제 #6
0
        private static JsValue Ceil(JsValue thisObject, JsValue[] arguments)
        {
            var x = TypeConverter.ToNumber(arguments.At(0));

            if (double.IsNaN(x))
            {
                return(JsNumber.DoubleNaN);
            }
            else if (NumberInstance.IsPositiveZero(x))
            {
                return(JsNumber.PositiveZero);
            }
            else if (NumberInstance.IsNegativeZero(x))
            {
                return(JsNumber.NegativeZero);
            }
            else if (double.IsPositiveInfinity(x))
            {
                return(JsNumber.DoublePositiveInfinity);
            }
            else if (double.IsNegativeInfinity(x))
            {
                return(JsNumber.DoubleNegativeInfinity);
            }

#if NETFRAMEWORK
            if (x < 0 && x > -1)
            {
                return(JsNumber.NegativeZero);
            }
#endif

            return(System.Math.Ceiling(x));
        }
예제 #7
0
        private static JsValue Sign(JsValue thisObject, JsValue[] arguments)
        {
            var x = TypeConverter.ToNumber(arguments.At(0));

            if (double.IsNaN(x))
            {
                return(JsNumber.DoubleNaN);
            }

            if (NumberInstance.IsPositiveZero(x) || NumberInstance.IsNegativeZero(x))
            {
                return(x);
            }

            if (double.IsPositiveInfinity(x))
            {
                return(1);
            }

            if (double.IsNegativeInfinity(x))
            {
                return(-1);
            }

            return(System.Math.Sign(x));
        }
예제 #8
0
        /// <summary>
        /// https://tc39.es/ecma262/#sec-math.max
        /// </summary>
        private static JsValue Max(JsValue thisObject, JsValue[] arguments)
        {
            if (arguments.Length == 0)
            {
                return(JsNumber.DoubleNegativeInfinity);
            }

            var highest = double.NegativeInfinity;

            foreach (var number in Coerced(arguments))
            {
                if (double.IsNaN(number))
                {
                    return(JsNumber.DoubleNaN);
                }

                if (NumberInstance.IsPositiveZero(number) && NumberInstance.IsNegativeZero(highest))
                {
                    highest = 0;
                }

                if (number > highest)
                {
                    highest = number;
                }
            }

            return(highest);
        }
예제 #9
0
        private static JsValue Asinh(JsValue thisObject, JsValue[] arguments)
        {
            var x = TypeConverter.ToNumber(arguments.At(0));

            if (double.IsInfinity(x) || NumberInstance.IsPositiveZero(x) || NumberInstance.IsNegativeZero(x))
            {
                return(x);
            }

            return(System.Math.Log(x + System.Math.Sqrt(x * x + 1.0)));
        }
예제 #10
0
        private JsValue Divide(JsValue lval, JsValue rval)
        {
            if (lval == Undefined.Instance || rval == Undefined.Instance)
            {
                return(Undefined.Instance);
            }
            else
            {
                var lN = TypeConverter.ToNumber(lval);
                var rN = TypeConverter.ToNumber(rval);

                if (double.IsNaN(rN) || double.IsNaN(lN))
                {
                    return(double.NaN);
                }

                if (double.IsInfinity(lN) && double.IsInfinity(rN))
                {
                    return(double.NaN);
                }

                if (double.IsInfinity(lN) && rN.Equals(0))
                {
                    if (NumberInstance.IsNegativeZero(rN))
                    {
                        return(-lN);
                    }

                    return(lN);
                }

                if (lN.Equals(0) && rN.Equals(0))
                {
                    return(double.NaN);
                }

                if (rN.Equals(0))
                {
                    if (NumberInstance.IsNegativeZero(rN))
                    {
                        return(lN > 0 ? -double.PositiveInfinity : -double.NegativeInfinity);
                    }

                    return(lN > 0 ? double.PositiveInfinity : double.NegativeInfinity);
                }

                return(lN / rN);
            }
        }
예제 #11
0
        private static JsValue DivideComplex(JsValue lval, JsValue rval)
        {
            if (lval.IsUndefined() || rval.IsUndefined())
            {
                return(Undefined.Instance);
            }
            else
            {
                var lN = TypeConverter.ToNumber(lval);
                var rN = TypeConverter.ToNumber(rval);

                if (double.IsNaN(rN) || double.IsNaN(lN))
                {
                    return(JsNumber.DoubleNaN);
                }

                if (double.IsInfinity(lN) && double.IsInfinity(rN))
                {
                    return(JsNumber.DoubleNaN);
                }

                if (double.IsInfinity(lN) && rN == 0)
                {
                    if (NumberInstance.IsNegativeZero(rN))
                    {
                        return(-lN);
                    }

                    return(lN);
                }

                if (lN == 0 && rN == 0)
                {
                    return(JsNumber.DoubleNaN);
                }

                if (rN == 0)
                {
                    if (NumberInstance.IsNegativeZero(rN))
                    {
                        return(lN > 0 ? -double.PositiveInfinity : -double.NegativeInfinity);
                    }

                    return(lN > 0 ? double.PositiveInfinity : double.NegativeInfinity);
                }

                return(lN / rN);
            }
        }
예제 #12
0
        private static JsValue Expm1(JsValue thisObject, JsValue[] arguments)
        {
            var x = TypeConverter.ToNumber(arguments.At(0));

            if (double.IsNaN(x) || NumberInstance.IsPositiveZero(x) || NumberInstance.IsNegativeZero(x) || double.IsPositiveInfinity(x))
            {
                return(arguments.At(0));
            }
            if (double.IsNegativeInfinity(x))
            {
                return(JsNumber.DoubleNegativeOne);
            }

            return(System.Math.Exp(x) - 1.0);
        }
예제 #13
0
        private static JsValue Asin(JsValue thisObject, JsValue[] arguments)
        {
            var x = TypeConverter.ToNumber(arguments.At(0));

            if (double.IsNaN(x) || (x > 1) || (x < -1))
            {
                return(JsNumber.DoubleNaN);
            }
            else if (NumberInstance.IsPositiveZero(x) || NumberInstance.IsNegativeZero(x))
            {
                return(x);
            }

            return(System.Math.Asin(x));
        }
예제 #14
0
        private static JsValue Atanh(JsValue thisObject, JsValue[] arguments)
        {
            var x = TypeConverter.ToNumber(arguments.At(0));

            if (double.IsNaN(x))
            {
                return(JsNumber.DoubleNaN);
            }

            if (NumberInstance.IsPositiveZero(x) || NumberInstance.IsNegativeZero(x))
            {
                return(x);
            }

            return(0.5 * System.Math.Log((1.0 + x) / (1.0 - x)));
        }
예제 #15
0
        public static bool SameValue(JsValue x, JsValue y)
        {
            var typea = TypeConverter.GetPrimitiveType(x);
            var typeb = TypeConverter.GetPrimitiveType(y);

            if (typea != typeb)
            {
                return(false);
            }

            if (typea == Types.None)
            {
                return(true);
            }
            if (typea == Types.Number)
            {
                var nx = TypeConverter.ToNumber(x);
                var ny = TypeConverter.ToNumber(y);

                if (double.IsNaN(nx) && double.IsNaN(ny))
                {
                    return(true);
                }

                if (nx.Equals(ny))
                {
                    if (nx.Equals(0))
                    {
                        // +0 !== -0
                        return(NumberInstance.IsNegativeZero(nx) == NumberInstance.IsNegativeZero(ny));
                    }

                    return(true);
                }

                return(false);
            }
            if (typea == Types.String)
            {
                return(TypeConverter.ToString(x) == TypeConverter.ToString(y));
            }
            if (typea == Types.Boolean)
            {
                return(TypeConverter.ToBoolean(x) == TypeConverter.ToBoolean(y));
            }
            return(x == y);
        }
예제 #16
0
        private static JsValue Max(JsValue thisObject, JsValue[] arguments)
        {
            if (arguments.Length == 0)
            {
                return(JsNumber.DoubleNegativeInfinity);
            }

            double max = TypeConverter.ToNumber(arguments.At(0));

            if (double.IsNaN(max))
            {
                return(JsNumber.DoubleNaN);
            }

            for (int i = 0; i < arguments.Length; i++)
            {
                var value = TypeConverter.ToNumber(arguments[i]);

                if (double.IsNaN(value))
                {
                    return(JsNumber.DoubleNaN);
                }

                if (max == 0 && value == 0)
                {
                    max = NumberInstance.IsNegativeZero(value)
                        ? max
                        : value;
                }
                else
                {
                    max = System.Math.Max(max, value);
                }
            }
            return(max);
        }
예제 #17
0
파일: JsNumber.cs 프로젝트: KurtGokhan/jint
 internal bool IsNegativeZero()
 {
     return(NumberInstance.IsNegativeZero(_value));
 }
예제 #18
0
        private static JsValue Atan2(JsValue thisObject, JsValue[] arguments)
        {
            var y = TypeConverter.ToNumber(arguments[0]);
            var x = TypeConverter.ToNumber(arguments[1]);

            // If either x or y is NaN, the result is NaN.
            if (double.IsNaN(x) || double.IsNaN(y))
            {
                return(double.NaN);
            }

            if (y > 0 && x == 0)
            {
                return(System.Math.PI / 2);
            }

            if (NumberInstance.IsPositiveZero(y))
            {
                // If y is +0 and x>0, the result is +0.
                if (x > 0)
                {
                    return(+0);
                }

                // If y is +0 and x is +0, the result is +0.
                if (NumberInstance.IsPositiveZero(x))
                {
                    return(+0);
                }

                // If y is +0 and x is −0, the result is an implementation-dependent approximation to +π.
                if (NumberInstance.IsNegativeZero(x))
                {
                    return(System.Math.PI);
                }

                // If y is +0 and x<0, the result is an implementation-dependent approximation to +π.
                if (x < 0)
                {
                    return(System.Math.PI);
                }
            }

            if (NumberInstance.IsNegativeZero(y))
            {
                // If y is −0 and x>0, the result is −0.
                if (x > 0)
                {
                    return(-0);
                }

                // If y is −0 and x is +0, the result is −0.
                if (NumberInstance.IsPositiveZero(x))
                {
                    return(-0);
                }

                // If y is −0 and x is −0, the result is an implementation-dependent approximation to −π.
                if (NumberInstance.IsNegativeZero(x))
                {
                    return(-System.Math.PI);
                }

                // If y is −0 and x<0, the result is an implementation-dependent approximation to −π.
                if (x < 0)
                {
                    return(-System.Math.PI);
                }
            }

            // If y<0 and x is +0, the result is an implementation-dependent approximation to −π/2.
            // If y<0 and x is −0, the result is an implementation-dependent approximation to −π/2.
            if (y < 0 && x == 0)
            {
                return(-System.Math.PI / 2);
            }

            // If y>0 and y is finite and x is +∞, the result is +0.
            if (y > 0 && !double.IsInfinity(y))
            {
                if (double.IsPositiveInfinity(x))
                {
                    return(+0);
                }

                // If y>0 and y is finite and x is −∞, the result if an implementation-dependent approximation to +π.
                if (double.IsNegativeInfinity(x))
                {
                    return(System.Math.PI);
                }
            }


            // If y<0 and y is finite and x is +∞, the result is −0.
            // If y<0 and y is finite and x is −∞, the result is an implementation-dependent approximation to −π.
            if (y < 0 && !double.IsInfinity(y))
            {
                if (double.IsPositiveInfinity(x))
                {
                    return(-0);
                }

                // If y>0 and y is finite and x is −∞, the result if an implementation-dependent approximation to +π.
                if (double.IsNegativeInfinity(x))
                {
                    return(-System.Math.PI);
                }
            }

            // If y is +∞ and x is finite, the result is an implementation-dependent approximation to +π/2.
            if (double.IsPositiveInfinity(y) && !double.IsInfinity(x))
            {
                return(System.Math.PI / 2);
            }

            // If y is −∞ and x is finite, the result is an implementation-dependent approximation to −π/2.
            if (double.IsNegativeInfinity(y) && !double.IsInfinity(x))
            {
                return(-System.Math.PI / 2);
            }

            // If y is +∞ and x is +∞, the result is an implementation-dependent approximation to +π/4.
            if (double.IsPositiveInfinity(y) && double.IsPositiveInfinity(x))
            {
                return(System.Math.PI / 4);
            }

            // If y is +∞ and x is −∞, the result is an implementation-dependent approximation to +3π/4.
            if (double.IsPositiveInfinity(y) && double.IsNegativeInfinity(x))
            {
                return(3 * System.Math.PI / 4);
            }

            // If y is −∞ and x is +∞, the result is an implementation-dependent approximation to −π/4.
            if (double.IsNegativeInfinity(y) && double.IsPositiveInfinity(x))
            {
                return(-System.Math.PI / 4);
            }

            // If y is −∞ and x is −∞, the result is an implementation-dependent approximation to −3π/4.
            if (double.IsNegativeInfinity(y) && double.IsNegativeInfinity(x))
            {
                return(-3 * System.Math.PI / 4);
            }

            return(System.Math.Atan2(y, x));
        }
예제 #19
0
        private static JsValue Pow(JsValue thisObject, JsValue[] arguments)
        {
            var x = TypeConverter.ToNumber(arguments[0]);
            var y = TypeConverter.ToNumber(arguments[1]);

            if (double.IsNaN(y))
            {
                return(double.NaN);
            }

            if (y == 0)
            {
                return(1);
            }

            if (double.IsNaN(x) && y != 0)
            {
                return(double.NaN);
            }

            if (System.Math.Abs(x) > 1)
            {
                if (double.IsPositiveInfinity(y))
                {
                    return(double.PositiveInfinity);
                }

                if (double.IsNegativeInfinity(y))
                {
                    return(+0);
                }
            }

            if (System.Math.Abs(x) == 1)
            {
                if (double.IsInfinity(y))
                {
                    return(double.NaN);
                }
            }

            if (System.Math.Abs(x) < 1)
            {
                if (double.IsPositiveInfinity(y))
                {
                    return(0);
                }

                if (double.IsNegativeInfinity(y))
                {
                    return(double.PositiveInfinity);
                }
            }

            if (double.IsPositiveInfinity(x))
            {
                if (y > 0)
                {
                    return(double.PositiveInfinity);
                }

                if (y < 0)
                {
                    return(+0);
                }
            }

            if (double.IsNegativeInfinity(x))
            {
                if (y > 0)
                {
                    if (System.Math.Abs(y % 2) == 1)
                    {
                        return(double.NegativeInfinity);
                    }

                    return(double.PositiveInfinity);
                }

                if (y < 0)
                {
                    if (System.Math.Abs(y % 2) == 1)
                    {
                        return(-0);
                    }

                    return(+0);
                }
            }

            if (NumberInstance.IsPositiveZero(x))
            {
                // If x is +0 and y>0, the result is +0.
                if (y > 0)
                {
                    return(0);
                }

                // If x is +0 and y<0, the result is +∞.
                if (y < 0)
                {
                    return(double.PositiveInfinity);
                }
            }


            if (NumberInstance.IsNegativeZero(x))
            {
                if (y > 0)
                {
                    // If x is −0 and y>0 and y is an odd integer, the result is −0.
                    if (System.Math.Abs(y % 2) == 1)
                    {
                        return(-0);
                    }

                    // If x is −0 and y>0 and y is not an odd integer, the result is +0.
                    return(+0);
                }

                if (y < 0)
                {
                    // If x is −0 and y<0 and y is an odd integer, the result is −∞.
                    if (System.Math.Abs(y % 2) == 1)
                    {
                        return(double.NegativeInfinity);
                    }

                    // If x is −0 and y<0 and y is not an odd integer, the result is +∞.
                    return(double.PositiveInfinity);
                }
            }

            // If x<0 and x is finite and y is finite and y is not an integer, the result is NaN.
            if (x < 0 && !double.IsInfinity(x) && !double.IsInfinity(y) && (int)y != y)
            {
                return(double.NaN);
            }

            return(System.Math.Pow(x, y));
        }
예제 #20
0
        private static JsValue Atan2(JsValue thisObject, JsValue[] arguments)
        {
            var y = TypeConverter.ToNumber(arguments.At(0));
            var x = TypeConverter.ToNumber(arguments.At(1));

            // If either x or y is NaN, the result is NaN.
            if (Money.IsNaN(x) || Money.IsNaN(y))
            {
                return(Money.NaN);
            }

            if (y > 0 && x.Equals(0))
            {
                return((Money)(decimal)(System.Math.PI / 2));
            }

            if (NumberInstance.IsPositiveZero(y))
            {
                // If y is +0 and x>0, the result is +0.
                if (x > 0)
                {
                    return(+0);
                }

                // If y is +0 and x is +0, the result is +0.
                if (NumberInstance.IsPositiveZero(x))
                {
                    return(+0);
                }

                // If y is +0 and x is −0, the result is an implementation-dependent approximation to +π.
                if (NumberInstance.IsNegativeZero(x))
                {
                    return((Money)(decimal)System.Math.PI);
                }

                // If y is +0 and x<0, the result is an implementation-dependent approximation to +π.
                if (x < 0)
                {
                    return((Money)(decimal)System.Math.PI);
                }
            }

            if (NumberInstance.IsNegativeZero(y))
            {
                // If y is −0 and x>0, the result is −0.
                if (x > 0)
                {
                    return(-0);
                }

                // If y is −0 and x is +0, the result is −0.
                if (NumberInstance.IsPositiveZero(x))
                {
                    return(-0);
                }

                // If y is −0 and x is −0, the result is an implementation-dependent approximation to −π.
                if (NumberInstance.IsNegativeZero(x))
                {
                    return((Money)(decimal) - System.Math.PI);
                }

                // If y is −0 and x<0, the result is an implementation-dependent approximation to −π.
                if (x < 0)
                {
                    return((Money)(decimal) - System.Math.PI);
                }
            }

            // If y<0 and x is +0, the result is an implementation-dependent approximation to −π/2.
            // If y<0 and x is −0, the result is an implementation-dependent approximation to −π/2.
            if (y < 0 && x.Equals(0))
            {
                return((Money)(decimal) - System.Math.PI / 2);
            }

            // If y>0 and y is finite and x is +∞, the result is +0.
            if (y > 0 && !Money.IsInfinity(y))
            {
                if (Money.IsPositiveInfinity(x))
                {
                    return(+0);
                }

                // If y>0 and y is finite and x is −∞, the result if an implementation-dependent approximation to +π.
                if (Money.IsNegativeInfinity(x))
                {
                    return((Money)(decimal)System.Math.PI);
                }
            }


            // If y<0 and y is finite and x is +∞, the result is −0.
            // If y<0 and y is finite and x is −∞, the result is an implementation-dependent approximation to −π.
            if (y < 0 && !Money.IsInfinity(y))
            {
                if (Money.IsPositiveInfinity(x))
                {
                    return(-0);
                }

                // If y>0 and y is finite and x is −∞, the result if an implementation-dependent approximation to +π.
                if (Money.IsNegativeInfinity(x))
                {
                    return((Money)(decimal) - System.Math.PI);
                }
            }

            // If y is +∞ and x is finite, the result is an implementation-dependent approximation to +π/2.
            if (Money.IsPositiveInfinity(y) && !Money.IsInfinity(x))
            {
                return((Money)(decimal)System.Math.PI / 2);
            }

            // If y is −∞ and x is finite, the result is an implementation-dependent approximation to −π/2.
            if (Money.IsNegativeInfinity(y) && !Money.IsInfinity(x))
            {
                return((Money)(decimal) - System.Math.PI / 2);
            }

            // If y is +∞ and x is +∞, the result is an implementation-dependent approximation to +π/4.
            if (Money.IsPositiveInfinity(y) && Money.IsPositiveInfinity(x))
            {
                return((Money)(decimal)System.Math.PI / 4);
            }

            // If y is +∞ and x is −∞, the result is an implementation-dependent approximation to +3π/4.
            if (Money.IsPositiveInfinity(y) && Money.IsNegativeInfinity(x))
            {
                return((Money)(decimal)(3 * System.Math.PI / 4));
            }

            // If y is −∞ and x is +∞, the result is an implementation-dependent approximation to −π/4.
            if (Money.IsNegativeInfinity(y) && Money.IsPositiveInfinity(x))
            {
                return((Money)(decimal) - System.Math.PI / 4);
            }

            // If y is −∞ and x is −∞, the result is an implementation-dependent approximation to −3π/4.
            if (Money.IsNegativeInfinity(y) && Money.IsNegativeInfinity(x))
            {
                return((Money)(decimal)(-3 * System.Math.PI / 4));
            }

            return((Money)(decimal)System.Math.Atan2(y.ToDouble(), x.ToDouble()));
        }
예제 #21
0
        private static JsValue Pow(JsValue thisObject, JsValue[] arguments)
        {
            var x = TypeConverter.ToNumber(arguments.At(0));
            var y = TypeConverter.ToNumber(arguments.At(1));

            if (Money.IsNaN(y))
            {
                return(Money.NaN);
            }

            if (y.Equals(0))
            {
                return(1);
            }

            if (Money.IsNaN(x) && !y.Equals(0))
            {
                return(Money.NaN);
            }

            if (Money.Abs(x) > 1)
            {
                if (Money.IsPositiveInfinity(y))
                {
                    return(Money.PositiveInfinity);
                }

                if (Money.IsNegativeInfinity(y))
                {
                    return(+0);
                }
            }

            if (Money.Abs(x).Equals(1))
            {
                if (Money.IsInfinity(y))
                {
                    return(Money.NaN);
                }
            }

            if (Money.Abs(x) < 1)
            {
                if (Money.IsPositiveInfinity(y))
                {
                    return(0);
                }

                if (Money.IsNegativeInfinity(y))
                {
                    return(Money.PositiveInfinity);
                }
            }

            if (Money.IsPositiveInfinity(x))
            {
                if (y > 0)
                {
                    return(Money.PositiveInfinity);
                }

                if (y < 0)
                {
                    return(+0);
                }
            }

            if (Money.IsNegativeInfinity(x))
            {
                if (y > 0)
                {
                    if (Money.Abs(y % 2).Equals(1))
                    {
                        return(Money.NegativeInfinity);
                    }

                    return(Money.PositiveInfinity);
                }

                if (y < 0)
                {
                    if (Money.Abs(y % 2).Equals(1))
                    {
                        return(-0);
                    }

                    return(+0);
                }
            }

            if (NumberInstance.IsPositiveZero(x))
            {
                // If x is +0 and y>0, the result is +0.
                if (y > 0)
                {
                    return(0);
                }

                // If x is +0 and y<0, the result is +∞.
                if (y < 0)
                {
                    return(Money.PositiveInfinity);
                }
            }


            if (NumberInstance.IsNegativeZero(x))
            {
                if (y > 0)
                {
                    // If x is −0 and y>0 and y is an odd integer, the result is −0.
                    if (Money.Abs(y % 2).Equals(1))
                    {
                        return(-0);
                    }

                    // If x is −0 and y>0 and y is not an odd integer, the result is +0.
                    return(+0);
                }

                if (y < 0)
                {
                    // If x is −0 and y<0 and y is an odd integer, the result is −∞.
                    if (Money.Abs(y % 2).Equals(1))
                    {
                        return(Money.NegativeInfinity);
                    }

                    // If x is −0 and y<0 and y is not an odd integer, the result is +∞.
                    return(Money.PositiveInfinity);
                }
            }

            // If x<0 and x is finite and y is finite and y is not an integer, the result is NaN.
            if (x < 0 && !Money.IsInfinity(x) && !Money.IsInfinity(y) && !y.Equals((int)y))
            {
                return(Money.NaN);
            }

            return((Money)(decimal)System.Math.Pow(x.ToDouble(), y.ToDouble()));
        }
예제 #22
0
        private static JsValue HandlePowUnlikely(double y, double x)
        {
            if (double.IsNaN(y))
            {
                return(JsNumber.DoubleNaN);
            }

            if (double.IsNaN(x))
            {
                return(JsNumber.DoubleNaN);
            }

            var absX = System.Math.Abs(x);

            if (absX > 1)
            {
                if (double.IsPositiveInfinity(y))
                {
                    return(JsNumber.DoublePositiveInfinity);
                }

                if (double.IsNegativeInfinity(y))
                {
                    return(JsNumber.PositiveZero);
                }
            }

            if (absX == 1)
            {
                if (double.IsInfinity(y))
                {
                    return(JsNumber.DoubleNaN);
                }
            }

            if (absX < 1)
            {
                if (double.IsPositiveInfinity(y))
                {
                    return(0);
                }

                if (double.IsNegativeInfinity(y))
                {
                    return(JsNumber.DoublePositiveInfinity);
                }
            }

            if (double.IsPositiveInfinity(x))
            {
                if (y > 0)
                {
                    return(JsNumber.DoublePositiveInfinity);
                }

                if (y < 0)
                {
                    return(JsNumber.PositiveZero);
                }
            }

            if (double.IsNegativeInfinity(x))
            {
                if (y > 0)
                {
                    if (System.Math.Abs(y % 2).Equals(1))
                    {
                        return(JsNumber.DoubleNegativeInfinity);
                    }

                    return(JsNumber.DoublePositiveInfinity);
                }

                if (y < 0)
                {
                    if (System.Math.Abs(y % 2).Equals(1))
                    {
                        return(JsNumber.NegativeZero);
                    }

                    return(JsNumber.PositiveZero);
                }
            }

            if (NumberInstance.IsPositiveZero(x))
            {
                // If x is +0 and y>0, the result is +0.
                if (y > 0)
                {
                    return(0);
                }

                // If x is +0 and y<0, the result is +∞.
                if (y < 0)
                {
                    return(JsNumber.DoublePositiveInfinity);
                }
            }


            if (NumberInstance.IsNegativeZero(x))
            {
                if (y > 0)
                {
                    // If x is −0 and y>0 and y is an odd integer, the result is −0.
                    if (System.Math.Abs(y % 2).Equals(1))
                    {
                        return(JsNumber.NegativeZero);
                    }

                    // If x is −0 and y>0 and y is not an odd integer, the result is +0.
                    return(JsNumber.PositiveZero);
                }

                if (y < 0)
                {
                    // If x is −0 and y<0 and y is an odd integer, the result is −∞.
                    if (System.Math.Abs(y % 2).Equals(1))
                    {
                        return(JsNumber.DoubleNegativeInfinity);
                    }

                    // If x is −0 and y<0 and y is not an odd integer, the result is +∞.
                    return(JsNumber.DoublePositiveInfinity);
                }
            }

            // If x<0 and x is finite and y is finite and y is not an integer, the result is NaN.
            if (x < 0 && !double.IsInfinity(x) && !double.IsInfinity(y) && !y.Equals((int)y))
            {
                return(JsNumber.DoubleNaN);
            }

            return(System.Math.Pow(x, y));
        }