Beispiel #1
0
        private static unsafe void DoubleToNumber(double value, int precision, ref NumberBuffer number)
        {
            number.precision = precision;
            if (!Double.IsFinite(value))
            {
                number.scale     = Double.IsNaN(value) ? ScaleNAN : ScaleINF;
                number.sign      = Double.IsNegative(value);
                number.digits[0] = '\0';
            }
            else
            {
                byte *src = stackalloc byte[_CVTBUFSIZE];
                int   sign;
                fixed(NumberBuffer *pNumber = &number)
                {
                    RuntimeImports._ecvt_s(src, _CVTBUFSIZE, value, precision, &pNumber->scale, &sign);
                }

                number.sign = sign != 0;

                char *dst = number.digits;
                if ((char)*src != '0')
                {
                    while (*src != 0)
                    {
                        *dst++ = (char)*src++;
                    }
                }
                *dst = '\0';
            }
        }
        internal static bool TryParseInt32(ReadOnlySpan <char> s, NumberStyles style, NumberFormatInfo info, out int result)
        {
            NumberBuffer number = default;

            result = 0;

            if ((style & ~NumberStyles.Integer) == 0)
            {
                // Optimized path for the common case of anything that's allowed for integer style.
                return(TryParseInt32IntegerStyle(s, style, info, out result, out _));
            }

            if (!TryStringToNumber(s, style, ref number, info, false))
            {
                return(false);
            }

            if ((style & NumberStyles.AllowHexSpecifier) != 0)
            {
                if (!HexNumberToInt32(ref number, ref result))
                {
                    return(false);
                }
            }
            else
            {
                if (!NumberToInt32(ref number, ref result))
                {
                    return(false);
                }
            }
            return(true);
        }
Beispiel #3
0
        private static unsafe bool NumberToUInt64(ref NumberBuffer number, ref ulong value)
        {
            int scale = number.scale;

            if (((scale > 20) || (scale < number.precision)) || number.sign)
            {
                return(false);
            }
            char *digits = number.digits;
            ulong num2   = 0L;

            while (--scale >= 0)
            {
                if (num2 > 0x1999999999999999L)
                {
                    return(false);
                }
                num2 *= (ulong)10L;
                if (digits[0] != '\0')
                {
                    digits++;
                    ulong num3 = num2 + (digits[0] - '0');
                    if (num3 < num2)
                    {
                        return(false);
                    }
                    num2 = num3;
                }
            }
            value = num2;
            return(true);
        }
Beispiel #4
0
        public static String FormatDecimal(Decimal value, String format, IFormatProvider provider)
        {
            NumberFormatInfo info = provider == null ? NumberFormatInfo.CurrentInfo : NumberFormatInfo.GetInstance(provider);

            NumberBuffer number = new NumberBuffer();

            DecimalToNumber(value, ref number);

            int  digits;
            char fmt = ParseFormatSpecifier(format, out digits);
            ValueStringBuilder sb;

            unsafe
            {
                char *stackPtr = stackalloc char[CharStackBufferSize];
                sb = new ValueStringBuilder(new Span <char>(stackPtr, CharStackBufferSize));
            }
            if (fmt != 0)
            {
                NumberToString(ref sb, ref number, fmt, digits, info, true);
            }
            else
            {
                NumberToStringFormat(ref sb, ref number, format, info);
            }
            return(sb.GetString());
        }
        internal static unsafe int ParseInt32(string s, NumberStyles style, NumberFormatInfo info)
        {
            fixed(byte *numberBufferBytes = new byte[NumberBuffer.NumberBufferBytes])
            {
                NumberBuffer number = new NumberBuffer(numberBufferBytes);
                int          i      = 0;

                StringToNumber(s, style, ref number, info, false);

                if ((style & NumberStyles.AllowHexSpecifier) != 0)
                {
                    if (!HexNumberToInt32(ref number, ref i))
                    {
                        throw new OverflowException(SR.Overflow_Int32);
                    }
                }
                else
                {
                    if (!NumberToInt32(ref number, ref i))
                    {
                        throw new OverflowException(SR.Overflow_Int32);
                    }
                }
                return(i);
            }
        }
Beispiel #6
0
        private static unsafe bool NumberToUInt64(ref NumberBuffer number, ref ulong value)
        {
            int i = number.scale;

            if (i > UInt64Precision || i < number.precision || number.sign)
            {
                return(false);
            }
            char *p = number.digits;

            Debug.Assert(p != null);
            ulong n = 0;

            while (--i >= 0)
            {
                if (n > (0xFFFFFFFFFFFFFFFF / 10))
                {
                    return(false);
                }
                n *= 10;
                if (*p != '\0')
                {
                    ulong newN = n + (ulong)(*p++ - '0');
                    // Detect an overflow here...
                    if (newN < n)
                    {
                        return(false);
                    }
                    n = newN;
                }
            }
            value = n;
            return(true);
        }
        internal static unsafe double ParseDouble(string value, NumberStyles options, NumberFormatInfo numfmt)
        {
            if (value == null)
            {
                throw new ArgumentNullException("value");
            }
            byte *       stackBuffer = stackalloc byte[0x72];
            NumberBuffer number      = new NumberBuffer(stackBuffer);
            double       num         = 0.0;

            if (!TryStringToNumber(value, options, ref number, numfmt, false))
            {
                string str = value.Trim();
                if (str.Equals(numfmt.PositiveInfinitySymbol))
                {
                    return(double.PositiveInfinity);
                }
                if (str.Equals(numfmt.NegativeInfinitySymbol))
                {
                    return(double.NegativeInfinity);
                }
                if (!str.Equals(numfmt.NaNSymbol))
                {
                    throw new FormatException(Environment.GetResourceString("Format_InvalidString"));
                }
                return(double.NaN);
            }
            if (!NumberBufferToDouble(number.PackForNative(), ref num))
            {
                throw new OverflowException(Environment.GetResourceString("Overflow_Double"));
            }
            return(num);
        }
        internal static unsafe bool TryParseUInt64(string s, NumberStyles style, NumberFormatInfo info, out ulong result)
        {
            fixed(byte *numberBufferBytes = new byte[NumberBuffer.NumberBufferBytes])
            {
                NumberBuffer number = new NumberBuffer(numberBufferBytes);

                result = 0;

                if (!TryStringToNumber(s, style, ref number, info, false))
                {
                    return(false);
                }

                if ((style & NumberStyles.AllowHexSpecifier) != 0)
                {
                    if (!HexNumberToUInt64(ref number, ref result))
                    {
                        return(false);
                    }
                }
                else
                {
                    if (!NumberToUInt64(ref number, ref result))
                    {
                        return(false);
                    }
                }
                return(true);
            }
        }
Beispiel #9
0
        internal static unsafe bool TryParseSingle(ReadOnlySpan <char> value, NumberStyles options, NumberFormatInfo numfmt, out float result)
        {
            NumberBuffer number = default;

            result = 0;
            double d = 0;

            if (!TryStringToNumber(value, options, ref number, numfmt, false))
            {
                return(false);
            }
            if (!NumberBufferToDouble(ref number, ref d))
            {
                return(false);
            }
            float castSingle = (float)d;

            if (float.IsInfinity(castSingle))
            {
                return(false);
            }

            result = castSingle;
            return(true);
        }
Beispiel #10
0
        private unsafe static Boolean NumberToUInt64(ref NumberBuffer number, ref UInt64 value)
        {
            Int32 i = number.scale;

            if (i > UInt64Precision || i < number.precision || number.sign)
            {
                return(false);
            }
            char *p = number.digits;

            Debug.Assert(p != null, "");
            UInt64 n = 0;

            while (--i >= 0)
            {
                if (n > (0xFFFFFFFFFFFFFFFF / 10))
                {
                    return(false);
                }
                n *= 10;
                if (*p != '\0')
                {
                    UInt64 newN = n + (UInt64)(*p++ - '0');
                    // Detect an overflow here...
                    if (newN < n)
                    {
                        return(false);
                    }
                    n = newN;
                }
            }
            value = n;
            return(true);
        }
        internal static unsafe ulong ParseUInt64(string value, NumberStyles options, NumberFormatInfo numfmt)
        {
            fixed(byte *numberBufferBytes = new byte[NumberBuffer.NumberBufferBytes])
            {
                NumberBuffer number = new NumberBuffer(numberBufferBytes);
                ulong        i      = 0;

                StringToNumber(value, options, ref number, numfmt, false);
                if ((options & NumberStyles.AllowHexSpecifier) != 0)
                {
                    if (!HexNumberToUInt64(ref number, ref i))
                    {
                        throw new OverflowException(SR.Overflow_UInt64);
                    }
                }
                else
                {
                    if (!NumberToUInt64(ref number, ref i))
                    {
                        throw new OverflowException(SR.Overflow_UInt64);
                    }
                }
                return(i);
            }
        }
Beispiel #12
0
        private static unsafe void DoubleToNumber(double value, int precision, ref NumberBuffer number)
        {
            number.precision = precision;
            if (DoubleHelper.Exponent(value) == 0x7ff)
            {
                number.scale     = DoubleHelper.Mantissa(value) != 0 ? ScaleNAN : ScaleINF;
                number.sign      = DoubleHelper.Sign(value);
                number.digits[0] = '\0';
            }
            else
            {
                byte *src = stackalloc byte[_CVTBUFSIZE];
                int   sign;
                fixed(NumberBuffer *pNumber = &number)
                {
                    RuntimeImports._ecvt_s(src, _CVTBUFSIZE, value, precision, &pNumber->scale, &sign);
                }

                number.sign = sign != 0;

                char *dst = number.digits;
                if ((char)*src != '0')
                {
                    while (*src != 0)
                    {
                        *dst++ = (char)*src++;
                    }
                }
                *dst = '\0';
            }
        }
        internal static unsafe bool TryParseSingle(string value, NumberStyles options, NumberFormatInfo numfmt, out float result)
        {
            fixed(byte *numberBufferBytes = new byte[NumberBuffer.NumberBufferBytes])
            {
                NumberBuffer number = new NumberBuffer(numberBufferBytes);

                result = 0;
                double d = 0;

                if (!TryStringToNumber(value, options, ref number, numfmt, false))
                {
                    return(false);
                }
                if (!NumberBufferToDouble(number, ref d))
                {
                    return(false);
                }
                float castSingle = (float)d;

                if (float.IsInfinity(castSingle))
                {
                    return(false);
                }

                result = castSingle;
                return(true);
            }
        }
Beispiel #14
0
        internal static unsafe bool TryParseInt64(ReadOnlySpan <char> s, NumberStyles style, NumberFormatInfo info, out long result)
        {
            NumberBuffer number = default;

            result = 0;

            if (!TryStringToNumber(s, style, ref number, info, false))
            {
                return(false);
            }

            if ((style & NumberStyles.AllowHexSpecifier) != 0)
            {
                if (!HexNumberToInt64(ref number, ref result))
                {
                    return(false);
                }
            }
            else
            {
                if (!NumberToInt64(ref number, ref result))
                {
                    return(false);
                }
            }
            return(true);
        }
Beispiel #15
0
        internal static unsafe bool TryParseSingle(string value, NumberStyles options, NumberFormatInfo numfmt, out float result)
        {
            byte *       stackBuffer = stackalloc byte[1 * 0x72];
            NumberBuffer number      = new NumberBuffer(stackBuffer);

            result = 0f;
            double num = 0.0;

            if (!TryStringToNumber(value, options, ref number, numfmt, false))
            {
                return(false);
            }
            if (!NumberBufferToDouble(number.PackForNative(), ref num))
            {
                return(false);
            }
            float f = (float)num;

            if (float.IsInfinity(f))
            {
                return(false);
            }
            result = f;
            return(true);
        }
Beispiel #16
0
            public static bool TryRunSingle(float value, int requestedDigits, ref NumberBuffer number)
            {
                float v = float.IsNegative(value) ? -value : value;

                Debug.Assert(v > 0);
                Debug.Assert(float.IsFinite(v));

                int  length;
                int  decimalExponent;
                bool result;

                if (requestedDigits == -1)
                {
                    DiyFp w = DiyFp.CreateAndGetBoundaries(v, out DiyFp boundaryMinus, out DiyFp boundaryPlus).Normalize();
                    result = TryRunShortest(in boundaryMinus, in w, in boundaryPlus, number.Digits, out length, out decimalExponent);
                }
                else
                {
                    DiyFp w = new DiyFp(v).Normalize();
                    result = TryRunCounted(in w, requestedDigits, number.Digits, out length, out decimalExponent);
                }

                if (result)
                {
                    Debug.Assert((requestedDigits == -1) || (length == requestedDigits));

                    number.Scale          = length + decimalExponent;
                    number.Digits[length] = (byte)('\0');
                    number.DigitsCount    = length;
                }

                return(result);
            }
Beispiel #17
0
        internal static unsafe double ParseDouble(ReadOnlySpan <char> value, NumberStyles options, NumberFormatInfo numfmt)
        {
            NumberBuffer number = default;
            double       d      = 0;

            if (!TryStringToNumber(value, options, ref number, numfmt, false))
            {
                //If we failed TryStringToNumber, it may be from one of our special strings.
                //Check the three with which we're concerned and rethrow if it's not one of
                //those strings.
                ReadOnlySpan <char> sTrim = value.Trim();
                if (sTrim.EqualsOrdinal(numfmt.PositiveInfinitySymbol))
                {
                    return(double.PositiveInfinity);
                }
                if (sTrim.EqualsOrdinal(numfmt.NegativeInfinitySymbol))
                {
                    return(double.NegativeInfinity);
                }
                if (sTrim.EqualsOrdinal(numfmt.NaNSymbol))
                {
                    return(double.NaN);
                }
                throw new FormatException(SR.Format_InvalidString);
            }

            if (!NumberBufferToDouble(ref number, ref d))
            {
                throw new OverflowException(SR.Overflow_Double);
            }

            return(d);
        }
Beispiel #18
0
        private static Boolean HexNumberToInt64(ref NumberBuffer number, ref Int64 value)
        {
            UInt64  passedValue = 0;
            Boolean returnValue = HexNumberToUInt64(ref number, ref passedValue);

            value = (Int64)passedValue;
            return(returnValue);
        }
Beispiel #19
0
        private static bool HexNumberToInt32(ref NumberBuffer number, ref int value)
        {
            uint num  = 0;
            bool flag = HexNumberToUInt32(ref number, ref num);

            value = (int)num;
            return(flag);
        }
Beispiel #20
0
        private static bool HexNumberToInt64(ref NumberBuffer number, ref long value)
        {
            ulong passedValue = 0;
            bool  returnValue = HexNumberToUInt64(ref number, ref passedValue);

            value = (long)passedValue;
            return(returnValue);
        }
Beispiel #21
0
        private static bool HexNumberToInt64(ref NumberBuffer number, ref long value)
        {
            ulong num  = 0L;
            bool  flag = HexNumberToUInt64(ref number, ref num);

            value = (long)num;
            return(flag);
        }
Beispiel #22
0
        private static bool HexNumberToInt32(ref NumberBuffer number, ref int value)
        {
            uint passedValue = 0;
            bool returnValue = HexNumberToUInt32(ref number, ref passedValue);

            value = (int)passedValue;
            return(returnValue);
        }
Beispiel #23
0
        private static unsafe bool HexNumberToUInt32(ref NumberBuffer number, ref uint value)
        {
            int i = number.scale;

            if (i > UInt32Precision || i < number.precision)
            {
                return(false);
            }
            char *p = number.digits;

            Debug.Assert(p != null);

            uint n = 0;

            while (--i >= 0)
            {
                if (n > ((uint)0xFFFFFFFF / 16))
                {
                    return(false);
                }
                n *= 16;
                if (*p != '\0')
                {
                    uint newN = n;
                    if (*p != '\0')
                    {
                        if (*p >= '0' && *p <= '9')
                        {
                            newN += (uint)(*p - '0');
                        }
                        else
                        {
                            if (*p >= 'A' && *p <= 'F')
                            {
                                newN += (uint)((*p - 'A') + 10);
                            }
                            else
                            {
                                Debug.Assert(*p >= 'a' && *p <= 'f');
                                newN += (uint)((*p - 'a') + 10);
                            }
                        }
                        p++;
                    }

                    // Detect an overflow here...
                    if (newN < n)
                    {
                        return(false);
                    }
                    n = newN;
                }
            }
            value = n;
            return(true);
        }
Beispiel #24
0
        private unsafe static Boolean HexNumberToUInt32(ref NumberBuffer number, ref UInt32 value)
        {
            Int32 i = number.scale;

            if (i > UInt32Precision || i < number.precision)
            {
                return(false);
            }
            Char *p = number.digits;

            Debug.Assert(p != null, "");

            UInt32 n = 0;

            while (--i >= 0)
            {
                if (n > ((UInt32)0xFFFFFFFF / 16))
                {
                    return(false);
                }
                n *= 16;
                if (*p != '\0')
                {
                    UInt32 newN = n;
                    if (*p != '\0')
                    {
                        if (*p >= '0' && *p <= '9')
                        {
                            newN += (UInt32)(*p - '0');
                        }
                        else
                        {
                            if (*p >= 'A' && *p <= 'F')
                            {
                                newN += (UInt32)((*p - 'A') + 10);
                            }
                            else
                            {
                                Debug.Assert(*p >= 'a' && *p <= 'f', "");
                                newN += (UInt32)((*p - 'a') + 10);
                            }
                        }
                        p++;
                    }

                    // Detect an overflow here...
                    if (newN < n)
                    {
                        return(false);
                    }
                    n = newN;
                }
            }
            value = n;
            return(true);
        }
Beispiel #25
0
        internal static unsafe double ParseDouble(string value, NumberStyles options, NumberFormatInfo numfmt)
        {
            byte *       stackBuffer = stackalloc byte[1 * 0x72];
            NumberBuffer number      = new NumberBuffer(stackBuffer);
            double       num         = 0.0;

            StringToNumber(value, options, ref number, numfmt, false);
            if (!NumberBufferToDouble(number.PackForNative(), ref num))
            {
                throw new OverflowException(Environment.GetResourceString("Overflow_Double"));
            }
            return(num);
        }
Beispiel #26
0
        internal unsafe static decimal ParseDecimal(ReadOnlySpan <char> value, NumberStyles options, NumberFormatInfo numfmt)
        {
            NumberBuffer number = default;
            decimal      result = 0;

            StringToNumber(value, options, ref number, numfmt, true);

            if (!NumberBufferToDecimal(ref number, ref result))
            {
                throw new OverflowException(SR.Overflow_Decimal);
            }
            return(result);
        }
        internal static unsafe decimal ParseDecimal(string value, NumberStyles options, NumberFormatInfo numfmt)
        {
            byte *       stackBuffer = stackalloc byte[0x72];
            NumberBuffer number      = new NumberBuffer(stackBuffer);
            decimal      num         = 0M;

            StringToNumber(value, options, ref number, numfmt, true);
            if (!NumberBufferToDecimal(number.PackForNative(), ref num))
            {
                throw new OverflowException(Environment.GetResourceString("Overflow_Decimal"));
            }
            return(num);
        }
        internal static unsafe decimal ParseDecimal(string value, NumberStyles options, NumberFormatInfo numfmt)
        {
            fixed(byte *numberBufferBytes = new byte[NumberBuffer.NumberBufferBytes])
            {
                NumberBuffer number = new NumberBuffer(numberBufferBytes);
                decimal      result = 0;

                StringToNumber(value, options, ref number, numfmt, true);

                if (!NumberBufferToDecimal(number, ref result))
                {
                    throw new OverflowException(SR.Overflow_Decimal);
                }
                return(result);
            }
        }
Beispiel #29
0
        internal static unsafe bool TryParseDouble(string value, NumberStyles options, NumberFormatInfo numfmt, out double result)
        {
            byte *       stackBuffer = stackalloc byte[1 * 0x72];
            NumberBuffer number      = new NumberBuffer(stackBuffer);

            result = 0.0;
            if (!TryStringToNumber(value, options, ref number, numfmt, false))
            {
                return(false);
            }
            if (!NumberBufferToDouble(number.PackForNative(), ref result))
            {
                return(false);
            }
            return(true);
        }
Beispiel #30
0
        //
        // This method is copied directly from CoreRT (which is in turn a C#-ized version of the CoreCLR C++ code.)
        //
        public static void RoundNumber(ref NumberBuffer number, int pos)
        {
            number.CheckConsistency();

            Span <byte> digits = number.Digits;

            int i = 0;

            while (i < pos && digits[i] != 0)
            {
                i++;
            }

            if (i == pos && digits[i] >= (byte)'5')
            {
                while (i > 0 && digits[i - 1] == (byte)'9')
                {
                    i--;
                }

                if (i > 0)
                {
                    digits[i - 1]++;
                }
                else
                {
                    number.Scale++;
                    digits[0] = (byte)'1';
                    i         = 1;
                }
            }
            else
            {
                while (i > 0 && digits[i - 1] == (byte)'0')
                {
                    i--;
                }
            }
            if (i == 0)
            {
                number.Scale      = 0;
                number.IsNegative = false;
            }
            digits[i] = 0;

            number.CheckConsistency();
        }