/// <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); }
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)); }
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)); }
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)); }
/// <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); }
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)); }
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)); }
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))); }
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); }
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)); }
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))); }
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)); }
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)); }
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())); }
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())); }
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)); }
internal bool IsPositiveZero() { return(NumberInstance.IsPositiveZero(_value)); }