public static EcmaValue ToBigIntN(EcmaValue value, int bits) { value = value.ToBigInt(); if (bits <= 0) { return(value0n); } if (bits == 64) { return(ToBigInt64(value)); } if (EcmaValue.GetNumberCoercion(value) == EcmaNumberType.BigInt64) { if (bits > 64) { return(value); } long r = 1 << bits; long m = 1 << (bits - 1); long v = value.ToInt64() % r; return(ToBigInt(v < -m ? v + r : v >= m ? v - r : v)); } BigInteger u = ToBigInteger(value); BigInteger bitsm0 = BigInteger.Pow(2, bits); BigInteger bitsm1 = BigInteger.Pow(2, bits - 1); BigInteger rem = BigInteger.Remainder(u, bitsm0); return(ToBigInt(rem < -bitsm1 ? rem + bitsm1 : rem >= bitsm1 ? rem - bitsm0 : rem)); }
public static EcmaValue ToBigUIntN(EcmaValue value, int bits) { value = value.ToBigInt(); if (bits <= 0) { return(value0n); } if (bits == 64) { return(ToBigUInt64(value)); } if (EcmaValue.GetNumberCoercion(value) == EcmaNumberType.BigInt64) { if (bits > 64) { return(ToBigInt(unchecked ((ulong)value.ToInt64()))); } long v = value.ToInt64(); long mask = (1 << bits) - 1; return(ToBigInt(unchecked ((ulong)(v & mask)))); } BigInteger u = ToBigInteger(value); BigInteger bitsm0 = BigInteger.Pow(2, bits); BigInteger rem = BigInteger.Remainder(u, bitsm0); return(ToBigInt(rem < 0 ? rem + bitsm0 : rem)); }
public static EcmaValue ToBigInt64(this EcmaValue value) { value = value.ToBigInt(); if (EcmaValue.GetNumberCoercion(value) == EcmaNumberType.BigInt64) { return(value); } byte[] byteArray = ((BigInteger)value.GetUnderlyingObject()).ToByteArray(); return(ToBigInt(BitConverter.ToInt64(byteArray, 0))); }
public static EcmaValue ToBigUInt64(this EcmaValue value) { value = value.ToBigInt(); if (EcmaValue.GetNumberCoercion(value) == EcmaNumberType.BigInt64) { long v = value.ToInt64(); return(v >= mod63?ToBigInt(new BigInteger(unchecked ((ulong)v))) : value); } BigInteger rem = BigInteger.Remainder((BigInteger)value.GetUnderlyingObject(), mod64); return(ToBigInt(rem < 0 ? rem + mod64 : rem)); }
public static EcmaValue Trunc(EcmaValue value) { if (value.Type != EcmaValueType.Number) { value = value.ToNumber(); } if (EcmaValue.GetNumberCoercion(value) != EcmaNumberType.Double) { return(value); } return(Math.Truncate(value.ToDouble())); }
public static EcmaValue Pow(this EcmaValue x, EcmaValue y) { switch (EcmaValue.GetNumberCoercion(x, y)) { case EcmaNumberType.BigInt: return(BigIntHelper.Pow(x, y)); case EcmaNumberType.BigInt64: return(BigIntHelper.Pow64(x, y)); } return(EcmaMath.Pow(x, y)); }
public static EcmaValue RightShift(this EcmaValue x, EcmaValue y) { switch (EcmaValue.GetNumberCoercion(x, y)) { case EcmaNumberType.BigInt: return(BigIntHelper.RightShift(x, y)); case EcmaNumberType.BigInt64: return(BigIntHelper.RightShift64(x, y)); } return((+x).ToInt32() >> (+y).ToInt32()); }
public static EcmaValue BitwiseOr(this EcmaValue x, EcmaValue y) { switch (EcmaValue.GetNumberCoercion(x, y)) { case EcmaNumberType.BigInt: return(BigIntHelper.BitwiseOr(x, y)); case EcmaNumberType.BigInt64: return(BigIntHelper.BitwiseOr64(x, y)); } return((+x).ToInt32() | (+y).ToInt32()); }
public static int Compare(EcmaValue x, EcmaValue y) { if (x.Type != EcmaValueType.BigInt) { return(-Compare(y, x)); } BigInteger bigInt = ToBigInteger(x); if (EcmaValue.GetNumberCoercion(y) == EcmaNumberType.Double) { return(((double)bigInt).CompareTo(y.ToDouble())); } return(bigInt.CompareTo(y.ToInt64())); }
public static EcmaValue Sign(EcmaValue value) { switch (EcmaValue.GetNumberCoercion(value)) { case EcmaNumberType.Int64: return(Math.Sign(value.ToInt64())); case EcmaNumberType.Int32: return(Math.Sign(value.ToInt32())); } double x = value.ToDouble(); return(Double.IsNaN(x) ? EcmaValue.NaN : x == 0 ? x : Math.Sign(x)); }
public static EcmaValue Abs(EcmaValue value) { switch (EcmaValue.GetNumberCoercion(value)) { case EcmaNumberType.Double: return(Math.Abs(value.ToDouble())); case EcmaNumberType.Int64: return(Math.Abs(value.ToInt64())); case EcmaNumberType.Int32: return(Math.Abs(value.ToInt32())); } return(Abs(value.ToNumber())); }
public static EcmaValue Ceil(EcmaValue value) { if (value.Type != EcmaValueType.Number) { value = value.ToNumber(); } if (EcmaValue.GetNumberCoercion(value) != EcmaNumberType.Double) { return(value); } double x = value.ToDouble(); double c = Math.Ceiling(x); return(c == 0 && x < 0 ? -0d : c); }
public static string ToString(EcmaValue value, int radix) { ThrowIfArgumentNotBigInt(value); if (radix < 2 || radix > 36) { throw new EcmaRangeErrorException(InternalString.Error.InvalidToStringRadix); } if (EcmaValue.GetNumberCoercion(value) == EcmaNumberType.BigInt64) { return(NumberPrototype.GetString(value.ToInt64(), radix)); } BigInteger bigInt = ToBigInteger(value); if (radix == 10) { return(bigInt.ToString()); } if (radix == 16) { return(bigInt.ToString("x")); } int digits = biggestLong[radix - 2]; bool isMinus = bigInt < 0; if (isMinus) { bigInt = -bigInt; } BigInteger divisor = BigInteger.Pow(radix, digits); StringBuilder sb = new StringBuilder(); while (bigInt > divisor) { bigInt = BigInteger.DivRem(bigInt, divisor, out BigInteger remainder); string s = NumberPrototype.GetString((long)remainder, radix); sb.Insert(0, s); if (s.Length < digits) { sb.Insert(0, "0", digits - s.Length); } } sb.Insert(0, NumberPrototype.GetString((long)bigInt, radix)); if (isMinus) { sb.Insert(0, '-'); } return(sb.ToString()); }
public static EcmaValue Round(EcmaValue value) { if (value.Type != EcmaValueType.Number) { value = value.ToNumber(); } if (EcmaValue.GetNumberCoercion(value) != EcmaNumberType.Double) { return(value); } double x = value.ToDouble(); if (x == 0) { return(x); } double r = Math.Floor(x + 0.5); return(r == 0 && x < 0 ? -0d : r); }