R get wrong result for a sum [duplicate] - r

This question already has answers here:
Why are these numbers not equal?
(6 answers)
Closed 9 years ago.
I am experiencing something weird with R recently. It can't get a sum write (even a simple one), I looked for any kind of precision issue but it did not seem it was the problem.
Any idea what could lead to that ?
> 0.1+0.2-0.4
Returns
> [1] -0.099999999999999977796

The answers to the question this will be closed as a duplicate of explains what is going on. But for a quick little thing hopefully this helps:
> options(digits = 22)
> .1 + .2 - 0.4
[1] -0.09999999999999997779554
> 0.1
[1] 0.1000000000000000055511
> 0.2
[1] 0.2000000000000000111022
> 0.4
[1] 0.4000000000000000222045
You can't represent 0.1 perfectly on a computer. It works with binary so only powers of 2 can be perfectly represented in decimal form. Some more examples:
> 1/2^2
[1] 0.25
> 1/2^3
[1] 0.125
> 1/2^4
[1] 0.0625
> 1/3
[1] 0.3333333333333333148296

You can set the display precision with something like
options(digits=10)
But this doesn't affect the actual precision of the calculation - most non-integer-values (such as 0.1) cannot be represented exactly in floating point arithmetic.
See here for an introduction into floating point arithmetic:
http://download.oracle.com/docs/cd/E19957-01/806-3568/ncg_goldberg.html

Related

How to deal with underflow in R? [duplicate]

This question already has answers here:
Dealing with very small numbers in R
(4 answers)
Closed 1 year ago.
I want to compute this number :
0.34911191 ^ 1157
I am using R programming language and it returns me 0 (this is an underflow problem). How I can fix it? Thanks.
Are you looking for something like this?
The CRAN package Brobdingnag has two vignettes explaining its use.
library(Brobdingnag)
x <- 1157 * log(0.34911191)
y <- as.brob(x)
exp(y)
#[1] +exp(-1217.6)
exp(y) < .Machine$double.neg.eps
#[1] TRUE
You can test the result using the Numerical Characteristics of the Machine (.Machine {base}), as shown below:
> 0.34911191 ^ 10 < .Machine$double.neg.eps
[1] FALSE
> 0.34911191 ^ 1157 < .Machine$double.neg.eps
[1] TRUE
double.neg.eps is a small positive floating-point number x such that 1 - x != 1.

0.5<0.5 returns TRUE in R? [duplicate]

This question already has answers here:
Why are these numbers not equal?
(6 answers)
Closed 2 years ago.
I came across a strange thing in R programming. When I simulate a sequence and want to judge whether the element is less than 0.5,
t=(1:1440)/1440
x=(t[720]-t[648])/0.1
x
#output:[1] 0.5
x<1/2
#output:[1] TRUE
x=0.5
x<1/2
#output:[1] FALSE
The two results are completely opposite and obviously the second result is what I want. Can anybody help me?
Floating point arithmetic is not exact in R, and the value you expect to be numerically exact to 0.5 may in fact be slightly more (or less). One possible workaround here would be to use rounding:
t <- (1:1440)/1440
x <- (t[720]-t[648]) / 0.1
round(x, 1) < 0.5

Floor not giving expected results when passed a calculation [duplicate]

This question already has answers here:
Why are these numbers not equal?
(6 answers)
Closed 5 years ago.
Why does only A out of A and B below equal 29? What is different about using a calculation as the x argument?
#A
floor(x = (1.45/0.05))
#B
floor(x = 29)
> #A
> floor(x = (1.45/0.05))
[1] 28
> #B
> floor(x = 29)
[1] 29
Like #bouncyball indicated it is a floating point problem.
If you go for example to this link and enter 1.45 or 0.05 you will notice that their binary representations are "infinitely" long (i.e. you can't write 1.45 with a finite string in binary).
Because your PC doesn't have infinite storage to store the digit he "chops" it off at some point - meaning he basically has your 1.45 as something like 1.49999999999 (nevermind the number of 9s) in his system. The same happens for 0.05.
Now your computer internally gets something like 28.9999999999999 - but he's not stupid when he outputs it. He knows, well 28.9999999999 is probably supposed to be 29 - so when he outputs it he just rounds. Except when you tell him explicitly to round using "floor" - then he rounds 28.99999999 to 28.
Hope that makes sense.

Logic regarding summation of decimals [duplicate]

This question already has answers here:
Why are these numbers not equal?
(6 answers)
Closed 8 years ago.
Does the last statement in this series of statements make logical sense to anybody else? R seems to give similar results for a small subset of possible sums of decimals under 1. I cannot recall any basic mathematical principles that would make this true, but it seems to be unlikely to be an error.
> 0.4+0.6
[1] 1
> 0.4+0.6==1.0
[1] TRUE
> 0.3+0.6
[1] 0.9
> 0.3+0.6==0.9
[1] FALSE
Try typing 0.3+0.6-0.9, on my system the result is -1.110223e-16 this is because the computer doesn't actually sum them as decimal numbers, it stores binary approximations, and sums those. And none of those numbers can be exactly represented in binary, so there is a small amount of error present in the calculations, and apparently it's small enough not to matter in the first one, but not the second.
Floating point arithmetic is not exact, but the == operator is. Use all.equal to compare two floating point values in R.
isTRUE(all.equal(0.3+0.6, 0.9))
You can also define a tolerance when calling all.equals.
isTRUE(all.equal(0.3+0.6, 0.9, tolerance = 0.001))

Negative values from simple calculation in R [duplicate]

This question already has answers here:
Why are these numbers not equal?
(6 answers)
Closed 9 years ago.
When I do a simple calculation with R 3.0.1, I got the following results. My question is that why the value of the first and the third equations are not equal to 0?
> -0.0082 + 0.0632 - 0.055
[1] 6.938894e-18
> -0.0082 - 0.055 + 0.0632
[1] 0
> 0.0632 - 0.0082 - 0.055
[1] 6.938894e-18
Only a finite set of real numbers can be represented exactly as a 64-bit floating-point values (which is what you are using). As it happens, none of the three values in your example fall into that category:
> format(0.0082, digits=20)
[1] "0.0082000000000000006911"
> format(0.0632, digits=20)
[1] "0.063200000000000006173"
> format(0.055, digits=20)
[1] "0.055000000000000000278"
This means that all of the computations are inexact.
Of particular relevance to your example is the fact that floating-point addition is not associative.
For an excellent backgrounder, see What Every Computer Scientist Should Know About Floating-Point Arithmetic.

Resources