예제 #1
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));
        }
예제 #2
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));
        }
예제 #3
0
 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)));
 }
예제 #4
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));
        }
예제 #5
0
 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()));
 }
예제 #6
0
        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));
        }
예제 #7
0
        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());
        }
예제 #8
0
        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());
        }
예제 #9
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()));
        }
예제 #10
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));
        }
예제 #11
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()));
        }
예제 #12
0
        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);
        }
예제 #13
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());
        }
예제 #14
0
        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);
        }