Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.

Commit

Permalink
Fixing the float/double parsing logic to handle exponents that are to…
Browse files Browse the repository at this point in the history
…o large/small (#23043)

* Fixing the float/double parsing logic to handle exponents that are too large/small

* Fixing the debug assert to use >= and <=

* Fixing the max exponents to be +1 to match what scale uses.
  • Loading branch information
tannergooding authored Mar 6, 2019
1 parent cb87aae commit 5a26509
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,9 @@ private static ulong NumberToFloatingPointBits(ref NumberBuffer number, in Float
{
Debug.Assert(number.GetDigitsPointer()[0] != '0');

Debug.Assert(number.Scale <= FloatingPointMaxExponent);
Debug.Assert(number.Scale >= FloatingPointMinExponent);

// The input is of the form 0.Mantissa x 10^Exponent, where 'Mantissa' are
// the decimal digits of the mantissa and 'Exponent' is the decimal exponent.
// We decompose the mantissa into two parts: an integer part and a fractional
Expand Down
43 changes: 39 additions & 4 deletions src/System.Private.CoreLib/shared/System/Number.Parsing.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,15 @@ internal partial class Number
private const int Int64Precision = 19;
private const int UInt64Precision = 20;

private const int DoubleMaxExponent = 309;
private const int DoubleMinExponent = -324;

private const int FloatingPointMaxExponent = DoubleMaxExponent;
private const int FloatingPointMinExponent = DoubleMinExponent;

private const int SingleMaxExponent = 39;
private const int SingleMinExponent = -45;

/// <summary>Map from an ASCII char to its hex value, e.g. arr['b'] == 11. 0xFF means it's not a hex digit.</summary>
internal static ReadOnlySpan<byte> CharToHexLookup => new byte[]
{
Expand Down Expand Up @@ -1964,18 +1973,44 @@ private static Exception GetException(ParsingStatus status, TypeCode type)
internal static double NumberToDouble(ref NumberBuffer number)
{
number.CheckConsistency();
double result;

if (number.Scale > DoubleMaxExponent)
{
result = double.PositiveInfinity;
}
else if (number.Scale < DoubleMinExponent)
{
result = 0;
}
else
{
ulong bits = NumberToFloatingPointBits(ref number, in FloatingPointInfo.Double);
result = BitConverter.Int64BitsToDouble((long)(bits));
}

ulong bits = NumberToFloatingPointBits(ref number, in FloatingPointInfo.Double);
double result = BitConverter.Int64BitsToDouble((long)(bits));
return number.IsNegative ? -result : result;
}

internal static float NumberToSingle(ref NumberBuffer number)
{
number.CheckConsistency();
float result;

if (number.Scale > SingleMaxExponent)
{
result = float.PositiveInfinity;
}
else if (number.Scale < SingleMinExponent)
{
result = 0;
}
else
{
uint bits = (uint)(NumberToFloatingPointBits(ref number, in FloatingPointInfo.Single));
result = BitConverter.Int32BitsToSingle((int)(bits));
}

uint bits = (uint)(NumberToFloatingPointBits(ref number, in FloatingPointInfo.Single));
float result = BitConverter.Int32BitsToSingle((int)(bits));
return number.IsNegative ? -result : result;
}
}
Expand Down

0 comments on commit 5a26509

Please sign in to comment.