Sign in to follow this  
Fl4sh

Why is this statement true

Recommended Posts

SiCrane    11839
Neither 0.1 nor 0.3 are exactly representable as finite precision binary floating point values. Therefore when doing operations that rely on exact representations you run into problems. Usually floating point comparisons for equality are done using a epsilon value to compensate for inexact representations. You may want to read this.

Share this post


Link to post
Share on other sites
Buckeye    10747
For the reasons SiCrane mentions, my compiler yields:

double f = 0.1; // = 0.1000000000001
double g = 0.3; // = 0.2999999999999
0.1*3 = 0.3000000000004; // != 0.2999999999999

NOTE: the exact number of digits isn't correct, but the principle remains.

Share this post


Link to post
Share on other sites
Fl4sh    30
Quote:
Original post by Quasimojo
Quote:
Original post by SiCraneYou may want to read this.


My head now officially hurts. >.<


I went into seizures when I glanced over that page.

_
lol jk.

Share this post


Link to post
Share on other sites
Buckeye    10747
Quote:
I went into seizures when I glanced over that page.

[smile]
Perhaps a simpler explanation:

When you specify a decimal (base-10) number in your code, the compiler attempts to convert that base-10 number to base-2 (binary).

In base-10, the placeholders for each digit represent a power of 10. E.g., 123.45 "means" 1 times 102 plus 2 times 101 plus 3 times 100 plus 4 times 10-1... etc.

To represent numbers in base-2, the placeholders for each digit represent powers of 2. E.g., 111.11 "means" 1 times 22 + 1 times 21 + 1 times 20 + 1 times 2-1 + 1 times 2-2.

The basic answer to your question is: 0.1 (decimal) and 0.3 (decimal) can't be represented exactly as the sum of powers of 2.

Your code 0.1*3 != 0.3 isn't comparing decimal numbers, it's comparing binary numbers.

Share this post


Link to post
Share on other sites
M2tM    948
To resolve your issue you can compare within the range of a calculated (or supplied) epsilon. Keep in mind errors accumulate with operations so this is more complicated than it sounds.

Pretty much never try to directly compare two floating point values with == or !=. It is likely you have a bug if you're doing something even if it happens to work for some values.

Another option is to use a fixed point library.

Share this post


Link to post
Share on other sites
Kambiz    758
Quote:
Original post by no such user
Quote:
Original post by M2tM
Another option is to use a fixed point library.

Fixed point doesn't change the fact that 0.1 and 0.3 aren't exactly representable by finite precision binary numbers.

When using fix point numbers you have the freedom to work in base 10 and represent 0.3 for example by the integer value 3000 which can be stored exactly in an int32. Though, usually base 2 is used to make use of fast bit shifts.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this