Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

floating point issue in R? [duplicate]

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?

like image 551
dnagirl Avatar asked Jul 29 '11 14:07

dnagirl


People also ask

What is the main problem with floating point representation?

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.

Why is floating point arithmetic inaccurate?

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.

What are the limitations of floating point representation?

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.

What is a floating point in R?

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.


2 Answers

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

like image 118
IRTFM Avatar answered Oct 05 '22 13:10

IRTFM


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.
like image 43
Michael Borgwardt Avatar answered Oct 05 '22 13:10

Michael Borgwardt