Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / .NET Framework / New Users / December 2007

Tip: Looking for answers? Try searching our database.

Weird double parsing

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Jimmy - 17 Dec 2007 12:21 GMT
Hi!

Simply put, the following code:

bool systemOk = true;
for (int i=0; i<10000; i++)
{
    double s = double.Parse("-606,11");

    if (!s.ToString("0.00").Equals("-606,11"))
    {
        systemOk = false;
        Console.WriteLine("On iteration #{0}. '606,11' was parsed as {1}", i, s);
    }
}

if (systemOk)
{
    Console.WriteLine("No error found!");
}

Console.WriteLine("Press enter to exit...");
Console.ReadLine();

...outputs the following the first run:
On iteration #2373. '606,11' was parsed as -606,01
On iteration #8949. '606,11' was parsed as -606,01
On iteration #9338. '606,11' was parsed as -606,01
On iteration #9643. '606,11' was parsed as -606,01
On iteration #9817. '606,11' was parsed as -606,01
Press enter to exit...

...and the following on the second run:
On iteration #4944. '606,11' was parsed as -606,01
On iteration #5911. '606,11' was parsed as -606,01
On iteration #8302. '606,11' was parsed as -606,01
On iteration #8518. '606,11' was parsed as -606,01
On iteration #8681. '606,11' was parsed as -606,01
Press enter to exit...

Should I consider suspect a hardware error? I've ran it on other computes
with no errors. Any hints on how to test the hardware to verify such
hypothesis?
Chris Shepherd - 17 Dec 2007 17:17 GMT
> Hi!
>
[quoted text clipped - 6 lines]
>
>     if (!s.ToString("0.00").Equals("-606,11"))
[...]

Maybe I'm silly, but wouldn't this never be true? Shouldn't it be:

if (!s.ToString("0,00").Equals("-606,11"))

Chris.
Jimmy - 17 Dec 2007 17:57 GMT
Thanks Chris!

I see your point. You really should be getting curious when you look at the
output. Given your question, there should be no output at all... :)

I apologize if this was a bit misleading. The reason is cultural
differences, I use a danish culture. Hence, "0.00" becomes "0,00".
Console.WriteLine(s.ToString("0.00",
System.Globalization.CultureInfo.CreateSpecificCulture("en-US")));
outputs: "-606.11"
Console.WriteLine(s.ToString("0.00",
System.Globalization.CultureInfo.CreateSpecificCulture("da-DK")));
outputs: "-606,11"

Perhaps the parsing problem itself has something to do with culture
settings. I don't know... I've tried different numbers and a common
denominator is that it is always a '1' that is wrongly parsed as a '0'. The
position of the digit differs from time to time, e.g.,  11,11 could be parsed
as 11,01 or 10,11

> > Hi!
> >
[quoted text clipped - 13 lines]
>
> Chris.
Chris Shepherd - 17 Dec 2007 18:24 GMT
> I see your point. You really should be getting curious when you look at the
> output. Given your question, there should be no output at all... :)

> I apologize if this was a bit misleading. The reason is cultural
> differences, I use a danish culture. Hence, "0.00" becomes "0,00".
[quoted text clipped - 4 lines]
> System.Globalization.CultureInfo.CreateSpecificCulture("da-DK")));
> outputs: "-606,11"

It wasn't misleading of you, and I was aware it's a cultural difference,
I just assumed that you would have to use the culture-specific proper
syntax on ToString. That appears to be completely wrong of me.
It's odd your code doesn't work, because if I create a culture object
for da-DK it works fine -- this code is working correctly for me:

CultureInfo dk = CultureInfo.CreateSpecificCulture("da-DK");
string stringVal = "-606,11";

bool systemOk = true;
for (int i = 0; i < 10000; i++)
{
    double s = double.Parse(stringVal, dk);

    if (!s.ToString("0.00",dk).Equals(stringVal))
    {
    systemOk = false;
    Console.WriteLine("On iteration #{0}. '{1}' was parsed as {2}", i,
stringVal, s);
    }
}

if (systemOk)
{
    Console.WriteLine("No error found!");
}

Console.WriteLine("Press enter to exit...");
Console.ReadLine();

Chris.
Chris Shepherd - 17 Dec 2007 18:29 GMT
> It wasn't misleading of you, and I was aware it's a cultural difference,
> I just assumed that you would have to use the culture-specific proper
> syntax on ToString. That appears to be completely wrong of me.
> It's odd your code doesn't work, because if I create a culture object
> for da-DK it works fine -- this code is working correctly for me:
[...]

To be clear, by "this code is working correctly for me" I mean that I
simply get the "No errors found!" message followed by "Press enter to
exit..." with no appearance of any of the "On iteration #" messages.

Chris.
Peter Duniho - 17 Dec 2007 18:20 GMT
>>      if (!s.ToString("0.00").Equals("-606,11"))
> [...]
>
> Maybe I'm silly, but wouldn't this never be true? Shouldn't it be:
>
> if (!s.ToString("0,00").Equals("-606,11"))

Nope.  The format string uses only the period for decimal, regardless of  
what the actual decimal separator is set to for the system, and the comma  
is specifically for something else (thousand separator or number scaling,  
depending on context).  This allows a format string to be  
language-independent.

The output from the program proves that the if() condition works as  
expected, since it is true occasionally.

Unfortunately, I don't have any useful information regarding the behavior  
the OP is seeing.  Hardware errors are rare, and I have seen at least one  
other example of floating point operations being affected by other things  
going on in the computer (code that leaves the FPU in an unusual state).  
But the error in this case is much greater than that noted in the other  
example I saw; a floating point error that's just part of the normal  
operation of the FPU should be _much_ smaller than that.

One thing about the posted code is that it relies on the formatting code,  
which means the error could be happening in the parse, or the format back  
to a string.  It would be useful and interesting to change the test so  
that it's two different loops, one that repeatedly parses the string, but  
compares it to a constant double instead of formatting it again, and  
another that starts with a constant double and repeatedly parses it.

That would help narrow down the problem, to identify whether it happens  
only when parsing, only when formatting, or in neither case separately (in  
other words, the two operations are interacting somehow to cause the  
error).  I suppose it's possible the test would reveal errors in both  
operations, but that seems unlikely to me.

I don't have enough knowledge to know how to _use_ that information, but  
it would at least hopefully help understand the error better.

Pete
Chris Shepherd - 17 Dec 2007 18:28 GMT
> Nope.  The format string uses only the period for decimal, regardless of
> what the actual decimal separator is set to for the system, and the
[quoted text clipped - 4 lines]
> The output from the program proves that the if() condition works as
> expected, since it is true occasionally.

Actually, it was *always* true for me. I could never get it to not
always either be true or false, even over 90000 iterations instead of
10000.

Are you seeing different results?

Chris.
Peter Duniho - 17 Dec 2007 18:49 GMT
> [...]
>>  The output from the program proves that the if() condition works as  
[quoted text clipped - 5 lines]
>
> Are you seeing different results?

I haven't even tried to run it.  By "is true occasionally" I just mean on  
the OP's computer.

I assume you mean that the result of the Equals() method is true.  The  
clause itself should always be _false_ on a computer that doesn't  
demonstrate the error (and as the OP says, so far he's only been able to  
reproduce it on his own computer...the code doesn't detect any error on a  
different computer).

Pete
Jimmy - 17 Dec 2007 18:41 GMT
Good idea. Tested with code:
bool systemOk = true;
Console.WriteLine("Testing with string comparison...");
for (int i=0; i<10000; i++)
{
    double s = double.Parse("-606,11");
    if (!s.ToString("0.00").Equals("-606,11"))
    {
        systemOk = false;
        Console.WriteLine("On iteration #{0}. '-606,11' was parsed as {1}", i, s);
    }
}

const double doubleCompare = -606.11d;
Console.WriteLine("Testing with double comparison...");
for (int i=0; i<10000; i++)
{
    double s = double.Parse("-606,11");
    if (s!=doubleCompare)
    {
        systemOk = false;
        Console.WriteLine("On iteration #{0}. '-606,11' was parsed as {1}", i, s);
    }
}
           
if (systemOk)
{
    Console.WriteLine("No error found!");
}

Console.WriteLine("Press enter to exit...");
Console.ReadLine();

Result:
Testing with string comparison...
On iteration #1016. '-606,11' was parsed as -606,01
On iteration #1055. '-606,11' was parsed as -606,01
On iteration #3110. '-606,11' was parsed as -606,01
On iteration #4366. '-606,11' was parsed as -606,01
On iteration #7388. '-606,11' was parsed as -606,01
On iteration #9022. '-606,11' was parsed as -606,01
Testing with double comparison...
On iteration #5. '-606,11' was parsed as -606,01
On iteration #594. '-606,11' was parsed as -606,01
On iteration #2242. '-606,11' was parsed as -606,01
On iteration #3648. '-606,11' was parsed as -606,01
On iteration #9918. '-606,11' was parsed as -606,01
Press enter to exit...

Weird!

> >>      if (!s.ToString("0.00").Equals("-606,11"))
> > [...]
[quoted text clipped - 37 lines]
>
> Pete
Peter Duniho - 17 Dec 2007 18:55 GMT
> Good idea. Tested with code:

Well, the code you posted isn't exactly what I meant.  Try this:

bool systemOk = true;
Console.WriteLine("Testing formatting...");
const double doubleCompare = -606.11d;
for (int i=0; i<10000; i++)
{
        string strT = doubleCompare.ToString("0.00");

    if (!strT.Equals("-606,11"))
    {
        systemOk = false;
        Console.WriteLine("On iteration #{0}. '-606,11' was formatted as {1}",  
i, strT);
    }
}

Console.WriteLine("Testing parsing...");
for (int i=0; i<10000; i++)
{
    double s = double.Parse("-606,11");
    if (s!=doubleCompare)
    {
        systemOk = false;
                // WARNING: if there's an error in the formatting, then  
the output here is
                // suspect, because it relies on the formatting to display  
the double! :)
        Console.WriteLine("On iteration #{0}. '-606,11' was parsed as {1}", i,  
s);
    }
}
           
if (systemOk)
{
    Console.WriteLine("No error found!");
}

Console.WriteLine("Press enter to exit...");
Console.ReadLine();
Jimmy - 18 Dec 2007 09:04 GMT
Ah, I see. The error only occur in relation to double.Parse. A ToString from
a double will not produce this error.

Here's probably the strangest piece of code I've written - the workaround
(taken from its context of course) :)

string tmpStr = thedoublestring; // eg. -606.11
double s;
string sStr;
do
{
    s = double.Parse(tmpStr);
    sStr = s.ToString("0.000000");
} while (!sStr.Equals(columns[selectedBeloebColumns[i]]));

> > Good idea. Tested with code:
>
[quoted text clipped - 38 lines]
> Console.WriteLine("Press enter to exit...");
> Console.ReadLine();

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.