Skip to content

Incorrect parsing of large floating point number: one bit offset #48648

@Ilia-Kosenkov

Description

@Ilia-Kosenkov

Description

Parsing large floating-point numbers sometimes produces a number that differs from the correct value by one bit.
In particular, "6250000000000000000000000000000000e-12" produces this error.
The problem is illustrated in this sharplab.io sample

Let @double = double.Parse("6250000000000000000000000000000000e-12", NumberStyles.Any).
The first indication of the parsing problem is that the default string representation of @double is "6.250000000000001E+21" (note an extra 1 at the end).
The (little-endian) byte-representation (obtained with e.g. BitConverter.GetBytes) is
"F74AE1C7022D7544".
This representation is unfortunately incorrect.
The value 6.25e21 can be represented more accurately by a double-precision variable, and the byte-representation of this value is in fact
"F64AE1C7022D7544".
The difference (for this particular number) is one bit (F6 vs F7).
The mentioned above sharplab sample nicely illustrates this problem.

This issue was discovered when dotnet's parsing methods were run against a large set of floating point tests provided in this repository
https://github.com/nigeltao/parse-number-fxx-test-data

The test case discussed in this issue is found in data/ibm-fpgen.txt, line 64724

Details 7C00 63A96816 44752D02C7E14AF6 6250000000000000000000000000000000e-12

There may be other (similar) issues, which I have not found yet.

Configuration

So far tested on Windows 10 x64 20H2 19042.804

  • dotnet @ Windows:

    • 5.0.103
    • 6.0.100-preview.1.21103.13
  • dotnet @ WSL2:

    • 5.0.103

Whatever backend sharplab.io uses also reproduces this error.

Regression?

Did not test earlier versions of dotnet.

Other information

This report would not be possible without https://github.com/nigeltao/parse-number-fxx-test-data project and its contributors.

I verified this particular parsing case against Rust implementation, see this rust demo.

Maybe related to #48119
Partially inspired by discussion around #48646.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions