Runtime: double.TryParse converts small exponent to negative infinity in .NET Core 3.0+

Created on 19 Nov 2019  Â·  7Comments  Â·  Source: dotnet/runtime

I recently added .NET Core 3.0 to the test matrix for a project and two tests started failing, one having to do with double parsing, the other with float. It boils down to this:

Console.WriteLine(Environment.Version);
const string input = "-1.79769313486232e309";
Console.WriteLine($"Input: {input}");
var success = double.TryParse(input, NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint | NumberStyles.AllowExponent | NumberStyles.AllowLeadingWhite | NumberStyles.AllowTrailingWhite, NumberFormatInfo.InvariantInfo, out var result);
Console.WriteLine($"double.TryParse: {success}: '{result}'");

On .NET Core 2.1, the output looks like this:

4.0.30319.42000
Input: -1.79769313486232e309
double.TryParse: False: '0'  

On .NET Core 3.0, the output looks like this:

3.0.0
Input: -1.79769313486232e309
double.TryParse: True: '-∞'

I know a number of changes went into .NET Core 3.0 regarding floating points, but this seems to be a regression. It's a small number, but I want to know if it's negative infinity or just too small to accurately fit within a double (same thing for value for float).

area-System.Numerics documentation up-for-grabs

Most helpful comment

I don't believe we have a good way of tracking all the locations needing updated today.

It's not much help, but some queries like this seem to throw up not too many hits, if you didn't already look at those places.

https://github.com/dotnet/dotnet-api-docs/search?q=%22System.Double.MinValue%22&unscoped_q=%22System.Double.MinValue%22
https://github.com/dotnet/dotnet-api-docs/search?q=%22System.Double.NegativeInfinity%22&unscoped_q=%22System.Double.NegativeInfinity%22

All 7 comments

@tannergooding Since it appears you did most of the work for the floating point stuff

This is by design. IEEE 754 specifies that operations are computed as if to infinite precision and unbounded range and then rounded to the nearest representable result.

"-1.79769313486232e309" as if to infinite precision and unbounded range is precisely "-1.79769313486232e309". It is greater than double.MinValue + Epsilon (where epsilon is the distance between x and its next representable value) so it rounds to -Infinity.

  • This cutoff is approx 1.7976931348623157e+308 + 1.9958403095347198e+292 = 1.797693134862315899584030953472e+308

Under the IEEE 754 spec, there isn't any value that can't be represented by a double/single. There are just values that are too large in magnitude or too small in magnitude. Values that are too large overflow to +/-Infinity and values that are too small underflow to +/-Zero.

It might be interesting to expose a parsing API which allows you to detect maximum error for a value ( you can't necessarily represent exact error as a double/single) or if the parsing was precise.

This sounds like it would fit your use case and would allow programs to more readily account for this error if it was important..

@tannergooding One issue here is that we introduce breaking changes without updating documentation:

https://docs.microsoft.com/en-us/dotnet/api/system.double.tryparse?view=netcore-3.0

The conversion fails if the s parameter is null or Empty, is not in a format compliant with style, represents a number less than MinValue or greater than MaxValue

According to the documentation, -∞ must fail the conversion.

Yes, there are apparently a few places where various remarks/etc need to be updated. I've been updating them as I've been made aware of them as I don't believe we have a good way of tracking all the locations needing updated today.

I don't believe we have a good way of tracking all the locations needing updated today.

It's not much help, but some queries like this seem to throw up not too many hits, if you didn't already look at those places.

https://github.com/dotnet/dotnet-api-docs/search?q=%22System.Double.MinValue%22&unscoped_q=%22System.Double.MinValue%22
https://github.com/dotnet/dotnet-api-docs/search?q=%22System.Double.NegativeInfinity%22&unscoped_q=%22System.Double.NegativeInfinity%22

Tagging subscribers to this area: @tannergooding
Notify danmosemsft if you want to be subscribed.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

omajid picture omajid  Â·  3Comments

btecu picture btecu  Â·  3Comments

aggieben picture aggieben  Â·  3Comments

noahfalk picture noahfalk  Â·  3Comments

matty-hall picture matty-hall  Â·  3Comments