Search code examples
c#floating-point.net-core-3.1

Why does Double.ToString("F1") behave differently in .NET Core 3.1?


I've updated a project from .NET Core 2.2 to .NET Core 3.1, and some of my unit tests are now failing in a surprising way.

For example, one of our tests is checking the formatting of a number (which should be rounded to 1 decimal place). The test has an input value of 1.65 and is expecting the result to be "1.7".

I've pared back the unit test to just the following, and it fails (the actual result is "1.6"):

Assert.Equal("1.7", 1.65.ToString("F1"));

I'm aware that floating-point handling was changed in .NET Core 3. However, from the description of those changes it looks like the differences should only affect the 15th decimal place.

I can only think that perhaps 1.65 is one of those numbers that's hard to represent in floating-point, and that it's actually being represented as 1.649999999999999 in the new world, which would indeed lead to it being rounded down?

Note: when I use the C# interactive console and enter 1.65.ToString("F1") it comes out as "1.7"!


Solution

  • There is a Github issue describing your exact issue which can be found here: https://github.com/dotnet/runtime/issues/1640

    That issue is marked as closed due to the root cause issue being a problem with Math.Round: https://github.com/dotnet/runtime/issues/1643

    So yes, this is unexpected behavior that is a bug in .NET. The bug has a milestone of Future which means it is not expected to be fixed in an upcoming release.