identical vs all.equal

Published by onesixx on

https://stackoverflow.com/questions/9508518/why-are-these-numbers-not-equal

숫자 비교시, 아주아주 정확할 필요가 없다면 identical() 보다는 all.equal()을 사용하는 편이 정신건강에 좋다.

> i <- 0.1
> i <- i + 0.05
> identical(i, 0.15)
[1] FALSE
> identical(round(i,1), 0.15)
[1] FALSE
> identical(round(i,2), 0.15)
[1] TRUE
> all.equal(i, 0.15)
[1] TRUE

> i <- 0.1
> i <- i + 0.06
> identical(i, 0.16)
[1] TRUE
> all.equal(i, 0.16)
[1] TRUE

 

https://cran.r-project.org/doc/FAQ/R-FAQ.html#Why-doesn_0027t-R-think-these-numbers-are-equal_003f

7.31 Why doesn’t R think these numbers are equal?

The only numbers that can be represented exactly in R’s numeric type are integers and fractions whose denominator is a power of 2. All other numbers are internally rounded to (typically) 53 binary digits accuracy. As a result, two floating point numbers will not reliably be equal unless they have been computed by the same algorithm, and not always even then. For example

R> a <- sqrt(2)
R> a * a == 2
[1] FALSE
R> a * a - 2
[1] 4.440892e-16
R> print(a * a, digits = 18)
[1] 2.00000000000000044

The function all.equal() compares two objects using a numeric tolerance of .Machine$double.eps ^ 0.5. If you want much greater accuracy than this you will need to consider error propagation carefully.

A discussion with many easily followed examples is in Appendix G “Computational Precision and Floating Point Arithmetic”, pages 753–771 of Statistical Analysis and Data Display: An Intermediate Course with Examples in R, Richard M. Heiberger and Burt Holland (Springer 2015, second edition). This appendix is a free download from http://link.springer.com/content/pdf/bbm%3A978-1-4939-2122-5%2F1.pdf.

For more information, see e.g. David Goldberg (1991), “What Every Computer Scientist Should Know About Floating-Point Arithmetic”, ACM Computing Surveys23/1, 5–48, also available via http://www.validlab.com/goldberg/paper.pdf.

Here is another example, this time using addition:

R> .3 + .6 == .9
[1] FALSE
R> .3 + .6 - .9
[1] -1.110223e-16
R> print(matrix(c(.3,  .6,  .9, .3 + .6)), digits = 18)
                     [,1]
[1,] 0.299999999999999989
[2,] 0.599999999999999978
[3,] 0.900000000000000022
[4,] 0.899999999999999911

 

Categories: R Basic

onesixx

Blog Owner

Leave a Reply

Your email address will not be published.