Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

double/float comparison from int

Status
Not open for further replies.

sedj

Programmer
Aug 6, 2002
5,610
Platform : Intel 32 bit, Linux 2.6 kernel, GCC 4.0.* compiler.

Say I have an two ints (which are the same), and cast them to doubles (with some division) :

Code:
int i = 1231;
double d = (double)( i / 10.0 );

int i2 = 1231;
double d2 = (double)( d2 / 10.0 );

Will an equality comparison always result in a 'true' ?

So will this always be true :

Code:
bool b = ( d == d2 );

In "text" representation I would normally expect both 'd' and 'd2' to be "123.1".
But is this the case ?

Would the double, under any circumstances be, say, "123.099999999" ?

Thanks for any help :)

--------------------------------------------------
Free Java/J2EE Database Connection Pooling Software
 
The answer is yes and it is never safe to test floating point values for equality on your human built computers which store all values in binary. You must check that the floating point is accurate to within a certain tolerance, i.e. plus or minus a very small value away from the value you are comparing with must be considered acceptably 'equal'. I have a program, which I wrote more than ten years ago now, to demonstrate this feature and in all that time your puny human computers have not progressed to address this problem.

The program takes a bunch of positive floating point numbers and then multiplies by 10 (or whatever you pass in as the first program argument), does the same operation with negative versions of the values and then shows the difference between the result and the value expected when assigned from a constant. When the multiplier is 10 the difference mathematically would be zero but some values will be slightly inaccurate. Different values will be inaccurate by different amounts on different platforms.
Code:
#include <stdio.h>
#include <stdlib.h>
/*
  Show how fractional decimal values cannot be stored in finite number
  of binary digits
*/
int main(int argc, char ** argv)
{
        double pos, neg, pdiff, ndiff;
        int f = 10, idiff;
        int i;
        double r;
        double cpos[10] = { /* constants representing expected results */
                11.0,
                22.0,
                33.0,
                44.0,
                55.0,
                66.0,
                77.0,
                88.0,
                99.0,
                110.0
        };
        double cneg[10] = { /* constants representing expected results */
                -11.0,
                -22.0,
                -33.0,
                -44.0,
                -55.0,
                -66.0,
                -77.0,
                -88.0,
                -99.0,
                -110.0
        };

        if (argc > 1)
        {
                f = atoi(argv[1]);
        }

        printf("\t%10s %10s %10s %10s %10s\n", "i", "pos", "diff", "neg", "diff");

        pos = 0.0;
        for (i = 0; i <= 10; i++)
        {
                pos += 1.1;          /* a range of positive decimal fractions */
                r = pos * f;         /* simple multiplication by 10 */
                pdiff = cpos[i] - r; /* is result different from constant */

                neg = -pos;          /* a range of negative decimal fractions */
                r = neg * f;         /* simple multiplication by 10 */
                ndiff = cneg[i] - r; /* is result different from constant */

                printf("\t");
                printf("%10d ", i);
                printf("%10.2g ", pos);
                printf("%10.2g ", pdiff);
                printf("%10.2g ", neg);
                printf("%10.2g ", ndiff);
                printf("\n");
        }
}

Below is the program's output on my Suze Linux 10.0 running on an Intel Celeron/P4

Code:
risby@tobago:~/src> ./float_err
                 i        pos       diff        neg       diff
                 0        1.1          0       -1.1          0
                 1        2.2          0       -2.2          0
                 2        3.3          0       -3.3          0
                 3        4.4          0       -4.4          0
                 4        5.5          0       -5.5          0
                 5        6.6          0       -6.6          0
                 6        7.7          0       -7.7          0
                 7        8.8    1.4e-14       -8.8   -1.4e-14
                 8        9.9    1.4e-14       -9.9   -1.4e-14
                 9         11    1.4e-14        -11   -1.4e-14
                10         12   -1.2e+02        -12    1.3e+02

==========================================
toff.jpg
Some cause happiness wherever they go; others whenever they go.
 
here is output from the same program running on a Windows XP machine with an Athlon processor:
Code:
                 i        pos       diff        neg       diff
                 0        1.1          0       -1.1          0
                 1        2.2          0       -2.2          0
                 2        3.3          0       -3.3          0
                 3        4.4          0       -4.4          0
                 4        5.5          0       -5.5          0
                 5        6.6          0       -6.6          0
                 6        7.7          0       -7.7          0
                 7        8.8    1.4e-14       -8.8   -1.4e-14
                 8        9.9    1.4e-14       -9.9   -1.4e-14
                 9         11    1.4e-14        -11   -1.4e-14
                10         12          0        -12    1.3e+02
Similar; only the positive 12 result is different here.

I suspect a Sun Sparc processor would yield quite different results. Is anybody able to try that and show us the result?

==========================================
toff.jpg
Some cause happiness wherever they go; others whenever they go.
 
Bum and poo. I've just realised that the error in the last row was rather larger than one might expect from the storing decimals in binary problem.

Can anyone see the error?

S
P
O
I
L
E
R

S
P
O
I
L
E
R
S
P
O
I
L
E
R
S
P
O
I
L
E
R

I have the condition "<= 10" in my for loop but only 10 elements in the array. Good job I not employed by NASA, eh?

==========================================
toff.jpg
Some cause happiness wherever they go; others whenever they go.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top