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); }
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); }
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); } }
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); } }
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); }
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); } }
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); } }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); } }
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); }
// // 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(); }