Negative values from simple calculation in R [duplicate] - r

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.

Related

R factorial() is not yielding the correct result [duplicate]

This question already has answers here:
Why are these numbers not equal?
(6 answers)
Closed 3 days ago.
I am trying to calculate the factorial of 52 in R. Astonishingly, I am getting contradicting results.
aaa<-1*2*3*4*5*6*7*8*9*10*11*12*13*14*15*16*17*18*19*20*21*22*23*24*25*26*27*28*29*30*31*32*33*34*35*36*37*38*39*40*41*42*43*44*45*46*47*48*49*50*51*52
bbb<-factorial(52)
aaa
[1] 80658175170943876845634591553351679477960544579306048386139594686464
bbb
[1] 80658175170944942408940349866698506766127860028660283290685487972352
aaa==bbb #False
What am I doing wrong?
This is a well known problem in computing with large numbers; R uses double-precision floating-point, the precision of which may vary by machine. Thats why you are getting multiple results across methods (including the online calculator in your comments). If you want to change your precision (in bits), one option is to use the Rmpfr package:
Rmpfr::mpfr(factorial(52),
6) # six bits
#1 'mpfr' number of precision 6 bits
#[1] 8.09e+67
Rmpfr::mpfr(factorial(52),
8) # eight bits
#1 'mpfr' number of precision 8 bits
#[1] 8.046e+67
This will allow you to obtain a result with the same value:
x <-Rmpfr::mpfr(1*2*3*4*5*6*7*8*9*10*11*12*13*14*15*16*17*18*19*20*21*22*23*24*25*26*27*28*29*30*31*32*33*34*35*36*37*38*39*40*41*42*43*44*45*46*47*48*49*50*51*52,
8)
y <- Rmpfr::mpfr(factorial(52),
8)
x == y
#[1] TRUE

Sum function in R not giving the expected answer [duplicate]

This question already has answers here:
How can I disable scientific notation?
(4 answers)
Why are these numbers not equal?
(6 answers)
Closed 3 years ago.
I have just started with R and am stuck on this bug.
fuel_efficiency<-c(28.2, 28.3, 28.4, 28.5, 29.0)
mean=28.48
deviation<-(fuel_efficiency-mean)
deviation
sum(deviation)
I have written this code to subtract the mean from the elements of the fuel efficiency vector to get the deviation vector. Then am trying to get the sum of the updated deviation vector.
The sum answer should return 0 but instead gives something like -3.552714e-15
The deviation vector is printed properly as expected.
#[1] -0.28 -0.18 -0.08 0.02 0.52
This are just rounding errors, -3.552714e-15 is a very, very small number:
Computers are notoriously bad at handling decimal numbers, (one could even say they are just not able to do it exactly). To overcome this R provides a function to check for equality:
all.equal(sum(deviation), 0)
This returns:
[1] TRUE
format(sum(deviation), scientific = FALSE)
Your answer is very close to zero. It's a rounding error. R uses IEEE 754 double-precision floating point numbers. Read more here: https://en.wikipedia.org/wiki/Double-precision_floating-point_format

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.

R get wrong result for a sum [duplicate]

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

Minimum evaluatable scientific value?

Does R store the smallest possibly representable scientific value?
To clarify: on my current machine:
>1e-300
[1] 1e-300
While
>1e-400
[1] 0
Through trial and error I know it is somewhere around the e-324 mark on my machine (where it also starts losing precision).
>1e-324
[1] 0
>5e-324
[1] 4.940656e-324
I've searched through the .Machine list and none of the values it stores contain either the value, or the exponent I'm looking for.
Edit:
Linked threads on the side indicate that this should be .Machine$double.eps, which is 2.220446e-16. Clearly this is no longer the case?
The smallest normalised is double.xmin, as described in this page. The Wikipedia entry is very interesting and has the subnormal limit which is 2^-1074, which is approximately 4.9406564584124654 x 10^-324 (from Wikipedia as Ben Bolker mentioned in the comments). Your output in R is matching this value.
double.epsilon is not what you think. It is the smallest number you can add to 1 such as you obtain a number which will be not recognised as 1.
I suggest you read about how the double are stored in memory and the basics of double operations. Once you understand how a double is stored the lower limit is obvious.
The accepted answer remains correct for base R, but using the package Rmpfr enables arbitrary precision. Example:
First, note issue in base R:
> p <- c("5e-600","2e-324","3e-324","4e-324", "5e-324","6e-324","7.1e-324","8e-324")
> as.numeric(p)
[1] 0.000000e+00 0.000000e+00 4.940656e-324 4.940656e-324 4.940656e-324 4.940656e-324
[7] 4.940656e-324 9.881313e-324
Observe that as we near the limit the precision is an issue and all values are 4.940656e-324.
Now use mpfr function from 'Rmpfr` package to cast the strings as floats:
> library(Rmpfr)
> .N <- function(.) mpfr(., precBits = 20)
> .N(p)
8 'mpfr' numbers of precision 20 bits
[1] 5.0000007e-600 2.00000e-324 2.9999979e-324 4.00000e-324 4.9999966e-324 5.9999959e-324
[7] 7.09999e-324 8.00000e-324

Resources