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 long ToArrayIndex() { if (!IsArrayIndex) { throw new InvalidOperationException(); } return(value.ToInt64()); }
public static EcmaValue LeftShift64(EcmaValue x, EcmaValue y) { ThrowIfArgumentNotBigInt(x); ThrowIfArgumentNotBigInt(y); long u = x.ToInt64(); long v = y.ToInt64(); if (u == 0 || v <= -64) { return(value0n); } if (v < 0) { return(ToBigInt(u >> -(int)v)); } if (v < 64) { long w = u << (int)v; if (u > 0 ? w > u : w < u) { return(ToBigInt(w)); } } if (v > Int32.MaxValue) { throw new EcmaRangeErrorException(InternalString.Error.BigIntOverflow); } try { return(ToBigInt(new BigInteger(u) << (int)v)); } catch (OutOfMemoryException) { throw new EcmaRangeErrorException(InternalString.Error.BigIntOverflow); } }
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 Negate64(EcmaValue x) { ThrowIfArgumentNotBigInt(x); long u = x.ToInt64(); return(ToBigInt(-u)); }
public static EcmaValue ExclusiveOr64(EcmaValue x, EcmaValue y) { ThrowIfArgumentNotBigInt(x); ThrowIfArgumentNotBigInt(y); long u = x.ToInt64(); long v = y.ToInt64(); return(ToBigInt(u ^ v)); }
public static EcmaValue Divide64(EcmaValue x, EcmaValue y) { ThrowIfArgumentNotBigInt(x); ThrowIfArgumentNotBigInt(y); long u = x.ToInt64(); long v = y.ToInt64(); return(ToBigInt(u / v)); }
public static EcmaValue BitwiseAnd64(EcmaValue x, EcmaValue y) { ThrowIfArgumentNotBigInt(x); ThrowIfArgumentNotBigInt(y); long u = x.ToInt64(); long v = y.ToInt64(); return(ToBigInt(u & v)); }
public static long ToInt64(EcmaValue value) { value = value.ToBigInt(); if (EcmaValue.GetNumberCoercion(value) == EcmaNumberType.BigInt64) { return(value.ToInt64()); } byte[] byteArray = ((BigInteger)value.GetUnderlyingObject()).ToByteArray(); return(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 Subtract64(EcmaValue x, EcmaValue y) { ThrowIfArgumentNotBigInt(x); ThrowIfArgumentNotBigInt(y); long u = x.ToInt64(); long v = y.ToInt64(); try { return(ToBigInt(checked (u - v))); } catch (OverflowException) { BigIntBinder bigInt = new BigIntBinder(new BigInteger(u) - new BigInteger(v)); return(bigInt.ToValue()); } }
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 Multiply64(EcmaValue x, EcmaValue y) { ThrowIfArgumentNotBigInt(x); ThrowIfArgumentNotBigInt(y); long a = x.ToInt64(); long b = y.ToInt64(); try { return(ToBigInt(checked (a * b))); } catch (OverflowException) { BigIntBinder bigInt = new BigIntBinder(new BigInteger(a) * new BigInteger(b)); return(bigInt.ToValue()); } }
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 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 RightShift64(EcmaValue x, EcmaValue y) { ThrowIfArgumentNotBigInt(x); ThrowIfArgumentNotBigInt(y); long u = x.ToInt64(); long v = y.ToInt64(); if (v < 0) { return(LeftShift64(x, -v)); } if (v >= 64) { return(value0n); } return(ToBigInt(u >> (int)v)); }
public static EcmaValue Pow64(EcmaValue x, EcmaValue y) { ThrowIfArgumentNotBigInt(x); ThrowIfArgumentNotBigInt(y); long u = x.ToInt64(); long v = y.ToInt64(); if (v < 0) { throw new EcmaRangeErrorException(InternalString.Error.ExponentMustBePositive); } try { return(ToBigInt(Math.Pow(u, v))); } catch (OverflowException) { } if (v > Int32.MaxValue) { throw new EcmaRangeErrorException(InternalString.Error.BigIntOverflow); } try { return(ToBigInt(BigInteger.Pow(u, (int)v))); } catch (OutOfMemoryException) { throw new EcmaRangeErrorException(InternalString.Error.BigIntOverflow); } }