-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Double doesn't Parse correctly #10110
Comments
@tannergooding is this expected? |
This is what a Java equivalent does:
|
@danmosemsft, no. There was quite a bit of work to make However, it looks like there is a bug in the reverse case (converting string to double). The relevant code is here: https://source.dot.net/#System.Private.CoreLib/shared/System/Number.Parsing.cs,458977730d4a33f6, but I haven't dug in to find out what is wrong. |
On my machines (i5-4670K, i5-6300U), on Debug and Release with
|
@tarekgh could you help with this one? |
@Suchiman, what locale are you? I'd like to try and reproduce your issue, since it doesn't appear to reproduce under my default. |
@cyberphone would be nice if you can share more info regarding your environment. I mean OS version, you user locale, your machine architecture. we just need to repro it first and then we can try to help to tell what is going on. |
@tarekgh, this repros on a clean Windows 10, English machine. There is definitely a bug somewhere in |
@tarekgh I have Windows 10 Pro, Version 1709, Build 16299.371, US Locale |
@cyberphone Thanks, I am able to repo it too now. |
https://github.com/dotnet/coreclr/issues/13615 is related/dup. |
Thanks, @jkotas for pointing to the other issue. I am seeing the direction is to port the parsing code from Roslyn to coreclr as mentioned in the comment https://github.com/dotnet/coreclr/issues/13615#issuecomment-326369056, I'll move this issue to the future milestone and leave it open to track porting the parsing code. |
A quick note too, I am seeing Roslyn implementation is using BigInteger class which I am not sure if there will be a perf issue there or we need to get optimized version. |
This is one possible direction. I think we should do our homework similar to what we have done for formatting. See what is the state of the art out there, and then pick the best option. |
The CoreCLR native code uses a highly optimized (and limited) |
@tarekgh Delete the above,I erred :-( BTW, I have a file with 100 million random and specific test values. This is how I found the problem. My application depends on perfect "roundtrips" including compatibility with ES6/V8. This is my application: It would be great if there was a Double.ToString("ES") method. |
@tannergooding Windows 10 Pro 1709 de-DE. |
@Suchiman My simple test program didn't take locale in consideration so '.' doesn't get interpreted as expected in DE.
|
@cyberphone Wow 🤦♂️ i didn't pay attention to that, with |
In case you are interested in 100M test values you may download the following file: Associated test program: using System;
using System.IO;
using System.Globalization;
namespace mathbug
{
class Program
{
static void Main(string[] args)
{
using (StreamReader sr = new StreamReader("c:\\es6\\numbers\\es6testfile100m.txt"))
{
string line;
// Read and display lines from the file until the end of
// the file is reached.
long counter = 0;
while ((line = sr.ReadLine()) != null)
{
string origIeeeHex = line.Substring(0, line.IndexOf(','));
while (origIeeeHex.Length < 16)
{
origIeeeHex = '0' + origIeeeHex;
}
ulong origIeeeBin = Convert.ToUInt64(origIeeeHex, 16);
double origIeee = BitConverter.Int64BitsToDouble((long)origIeeeBin);
string number2Parse = line.Substring(line.IndexOf(',') + 1);
if (++counter % 100000 == 0)
{
Console.WriteLine("Count=" + counter);
}
double parsedIeee = double.Parse(number2Parse, NumberStyles.Float, CultureInfo.InvariantCulture);
String parsedIeeeHex = Convert.ToString(BitConverter.DoubleToInt64Bits(parsedIeee), 16);
while (parsedIeeeHex.Length < 16)
{
parsedIeeeHex = '0' + parsedIeeeHex;
}
bool roundTripOk = parsedIeee.ToString("G17").Equals(origIeee.ToString("G17"));
if (origIeee != parsedIeee || !roundTripOk)
{
Console.WriteLine("Number2Parse={0,-24:S} C#={1,-24:S} Original=" + origIeeeHex +
" Parsed=" + parsedIeeeHex +
" Roundtrip OK=" +roundTripOk, number2Parse, origIeee.ToString("G17"));
}
}
}
}
}
} |
Hi Guys, |
@cyberphone the fix is in master which means it will be in.NET Core 3.0. Another preview will be out in not long. There are no plans to port to.NET Framework, I think. |
@danmosemsft thanx! |
And it is working as well. SUPER! |
That is great @cyberphone. Any interest in making a contribution of your own perhaps? Lots of up for grabs labeled issues. :) |
@danmosemsft Well, there are contributions and contributions... |
While doing some mathematical stuff that worked fine in Java I found that C# / .NET does a rather poor job on parsing double values:
You can verify in any browser that 4.3413853813852797e+192 and 4.34138538138528e+192 are distinct values. Version: CLR v4.0.30319
The text was updated successfully, but these errors were encountered: