Re: Wrong results when comparing negative double variables in an if statement
From: Gordon Burditt (gordonb.4lxna_at_burditt.org)
Date: 04/23/04
- Next message: Kenneth Brody: "Re: Valid operations on pointers in C"
- Previous message: Keith Thompson: "Re: Rob Pike's simple Include rule"
- In reply to: John: "Wrong results when comparing negative double variables in an if statement"
- Next in thread: Darrell Grainger: "Re: Wrong results when comparing negative double variables in an if statement"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Date: 23 Apr 2004 20:14:33 GMT
>I encountered a strange problem while debugging C code for a
>Windows-based application in LabWindows CVI V5.5, which led me to
>write the test code below. I tried this code with a different compiler
>and got the same erroneous result on two different PCs (with OS Win98
>& Win98SE), so it appears to be a problem with ANSI C. I thought that
>negative double variables could be compared as easily and *reliably*
>as integers, but apparently not?
Rounding error. If you're going to use floating-point numbers,
learn to live with it. And it's not only *NEGATIVE* numbers
that have the problem.
>#include <ansi_c.h>
Non-standard include file.
>
>void main (void)
main returns int, not void!
>{
>double a = -2.0, b = -2.0;
>
>if (a > b)
> printf("a is greater than b because a is %f and b is %f\n", a, b);
>else
> printf("a is not greater than b because a is %f and b is %f\n", a,
>b);
>
>a -= 0.01; // decrease value of a by 0.01
>a += 0.01; // restore original value of a by increasing it by 0.01
No, you are NOT guaranteed that this will restore a to the original
value. There is no exact value of 0.01 in binary floating point.
>
>if (a > b)
> printf("a is greater than b because a is %f and b is %f\n", a, b);
>else
> printf("a is not greater than b because a is %f and b is %f\n", a,
>b);
Print the numbers with unreasonably large precision, say %200.100f,
and you'll see what is going on. Also try printing 0.01 with
unreasonably large precision. Note that you're doing this for
debugging purposes, not because floating-point numbers have hundreds
of digits of accuracy, which they don't on any real machines I
have encountered, barring use of bignum packages which aren't
native C types.
>}
>
>The output as copied from the emulated DOS window is:
>
>a is not greater than b because a is -2.000000 and b is -2.000000
>a is greater than b because a is -2.000000 and b is -2.000000
>
>If I decrement and then increment a by 0.001, everything is fine, so
>it doesn't look like there is a problem with the small magnitude of
>the fractions.
There is no exact value of 0.001 in binary floating point, either.
>I would be grateful for any solutions or suggestions to this problem
>so that I can process *all* fractions correctly.
Rounding error. Learn to live with it. (Very few decimal numbers
other than exact integers have exact representations in binary
floating point, a few exceptions being .5, .25, .75, .125, .375,
.625, and .875.) You might want to do this by explicitly rounding the
number yourself, and do NOT depend on what happens at the
exactly-half-way points.
Money is best represented as an integer quantity of the smallest
unit of currency you have to deal with (which might be cents in the
USA, or might be ten-thousandths of cents if you're an electric
company setting a price per kilowatt-hour to bill customers). You
can store this in an integer or floating type as appropriate for
the application. Bill Gates wouldn't want to use a 32-bit unsigned
long in cents (overflows at slightly under $43 million) for his net
worth, but it's fine for your average kid running a lemonade stand.
double or (for C99) long long might work well for all but the biggest
companies/governments.
Gordon L. Burditt
- Next message: Kenneth Brody: "Re: Valid operations on pointers in C"
- Previous message: Keith Thompson: "Re: Rob Pike's simple Include rule"
- In reply to: John: "Wrong results when comparing negative double variables in an if statement"
- Next in thread: Darrell Grainger: "Re: Wrong results when comparing negative double variables in an if statement"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Relevant Pages
|