usp
usp

Reputation: 111

Why there is no errors while multiplying floating point numbers?

I need some clearification about floating point math.

I have wrote some code for the learning purpouses:

#include "stdio.h"

int main (int argc, char const *argv[])
{
    int i;
    double a=1.0/10.0;
    double sum=0;

    for(i = 0; i < 10; ++i)
        sum+=a;

    printf("%.17G\n", 10*a );
    printf("%d\n", (10*a == 1.0) );

    printf("%.17G\n", sum );
    printf("%d\n", (sum == 1.0) );

    return 0;
}

and the output it gives is:

    1
    1
    0.99999999999999989
    0

Why (sum == 1.0) - is false is pretty understandabale, but why multiplying gives the right answer without the error?

Thanks.

Upvotes: 3

Views: 1746

Answers (3)

old_timer
old_timer

Reputation: 71516

There are a lot of problems with your code.

floating point on a computer is base 2. You cannot represent 0.1 exactly in floating point (just like you cant represent 1/3rd in base 10 compared apples to apples), so any other assumptions after that (multiply by 10 and expect it to be a one for example) are bad.

The single multiply of 10 times 0.1 only incurs one times the error. The multiple additions incur 10 times the error. Rounding fixes the 10 times 0.1 when converting to integer making it look like it actually worked. Rounding being yet another feature of IEEE floating point, the rounding mode used by default on your system as well as whatever the 1/10th became again basically made the single multiply look like it worked.

next problem is you are doing equals comparisons with floating point and I assume having some sort of expectation. dont use equals on float, period. Certainly not with numbers like this that cannot be represented exactly in floating point.

try a number like 1/16th for example or 1/8th instead of 1/10th...

Upvotes: 0

R.. GitHub STOP HELPING ICE
R.. GitHub STOP HELPING ICE

Reputation: 215193

When performing the repeated addition, there are 9 roundings taking place: the first result a+a is always exactly representable, but after that, further additions are inexact since the base-2 exponents of the addends are not equal.

When performing the multiplication, there's only a single rounding, and it happens to give you the result you wanted.

Upvotes: 1

mah
mah

Reputation: 39797

If you look at the actual assembly language produced, you'll find that the compiler is not generating the single multiplication you're asking for. Instead, it's simply providing the actual value. If you turn off optimization you might get the results you're expecting (unless your compiler optimizes this anyway).

Upvotes: 2

Related Questions