Possible Duplicate:
Why are these numbers not equal?
The below expression, which evaluates to 0.1, is considered larger than 0.1.
> round(1740/600,0) - 1740/600
[1] 0.1
> (round(1740/600,0) - 1740/600) <= 0.1
[1] FALSE //???!!???
> (round(1740/600,0) - 1740/600) <= 0.1000000000000000000000000000000000000001
[1] TRUE
Thinking that the issue might be due to rounding I tried this with the same result:
> 3 - 2.9
[1] 0.1
> (3 - 2.9) <=0.1
[1] FALSE
So, what gives and how do I fix it without fudging the cutoff?
Accuracy in floating point representation is governed by number of significant bits, whereas range is limited by exponent. Not all real numbers can exactly be represented in floating point format.
Because often-times, they are approximating rationals that cannot be represented finitely in base 2 (the digits repeat), and in general they are approximating real (possibly irrational) numbers which may not be representable in finitely many digits in any base.
Floating-point numbers suffer from a loss of precision when represented with a fixed number of bits (e.g., 32-bit or 64-bit). This is because there is an infinite amount of real numbers, even within a small range like 0.0 to 0.1.
A floating point number has a value written in binary, and an indication of how many binary places to move over (by the way, that's where “floating” comes in). There are two important things to remember about floating point numbers: they are limited in the number of real numbers they represent.
There are R functions that automatically take sensible approaches to the "equality problem":
> (3 - 2.9) <=0.1
#[1] FALSE
> all.equal( (3 - 2.9) , 0.1)
#[1] TRUE
It uses the sqrt of R's smallest positive floating point number as its default threshold, so it handles multiplications and division propagated errors. Ends up being around 1e-08
From the Floating-Point Guide:
Why don’t my numbers, like 0.1 + 0.2 add up to a nice round 0.3, and instead I get a weird result like 0.30000000000000004?
Because internally, computers use a format (binary floating-point) that cannot accurately represent a number like 0.1, 0.2 or 0.3 at all.
When the code is compiled or interpreted, your “0.1” is already rounded to the nearest number in that format, which results in a small rounding error even before the calculation happens.
What can I do to avoid this problem?
That depends on what kind of calculations you’re doing.
- If you really need your results to add up exactly, especially when you work with money: use a special decimal datatype.
- If you just don’t want to see all those extra decimal places: simply format your result rounded to a fixed number of decimal places when displaying it.
- If you have no decimal datatype available, an alternative is to work with integers, e.g. do money calculations entirely in cents. But this is more work and has some drawbacks.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With