示例#1
0
        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));
        }
示例#2
0
 public long ToArrayIndex()
 {
     if (!IsArrayIndex)
     {
         throw new InvalidOperationException();
     }
     return(value.ToInt64());
 }
示例#3
0
        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);
            }
        }
示例#4
0
        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));
        }
示例#5
0
        public static EcmaValue Negate64(EcmaValue x)
        {
            ThrowIfArgumentNotBigInt(x);
            long u = x.ToInt64();

            return(ToBigInt(-u));
        }
示例#6
0
        public static EcmaValue ExclusiveOr64(EcmaValue x, EcmaValue y)
        {
            ThrowIfArgumentNotBigInt(x);
            ThrowIfArgumentNotBigInt(y);
            long u = x.ToInt64();
            long v = y.ToInt64();

            return(ToBigInt(u ^ v));
        }
示例#7
0
        public static EcmaValue Divide64(EcmaValue x, EcmaValue y)
        {
            ThrowIfArgumentNotBigInt(x);
            ThrowIfArgumentNotBigInt(y);
            long u = x.ToInt64();
            long v = y.ToInt64();

            return(ToBigInt(u / v));
        }
示例#8
0
        public static EcmaValue BitwiseAnd64(EcmaValue x, EcmaValue y)
        {
            ThrowIfArgumentNotBigInt(x);
            ThrowIfArgumentNotBigInt(y);
            long u = x.ToInt64();
            long v = y.ToInt64();

            return(ToBigInt(u & v));
        }
示例#9
0
 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));
 }
示例#10
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));
        }
示例#11
0
        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());
            }
        }
示例#12
0
        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()));
        }
示例#13
0
        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());
            }
        }
示例#14
0
        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));
        }
示例#15
0
        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()));
        }
示例#16
0
        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());
        }
示例#17
0
        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));
        }
示例#18
0
        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);
            }
        }