Why is this easy comparison false? [duplicate] - r

This question already has answers here:
Why are these numbers not equal?
(6 answers)
Closed 8 years ago.
Why does this simple statement evaluate to FALSE in R?
mean(c(7.18, 7.13)) == 7.155
Furthermore, what do I have to do in order to make this a TRUE statement? Thanks!

Floating point arithmetic is not exact. The answer to this question has more information.
You can actually see this:
> print(mean(c(7.18,7.13)), digits=16)
[1] 7.154999999999999
> print(7.155, digits=16)
[1] 7.155
In general, do not compare floating point numbers for equality (this applies to pretty much every programming language, not just R).
You can use all.equal to do an inexact comparison:
> all.equal(mean(c(7.18,7.13)), 7.155)
[1] TRUE

It's probably due to small rounding error. Rounding to the third decimal place shows that they are equal:
round(mean(c(7.18, 7.13)), 3) == 7.155
Generally, don't rely on numerical comparisons to give expected logical outputs :)

Related

%in% on numeric values returns wrong result

6969277959563657216 is not one of the following numbers, yet %in% returns TRUE.
6969277959563657216 %in% c(6972646901044805634,
6935914801507893250,
6930019021496532993,
6969277959563657217,
7005257783989764866)
[1] TRUE
Why is this?
The reason is that most computer programs work with a precision of approx. 16 digits, see FAQ 7.31 Why doesn’t R think these numbers are equal? and the link therein. The interpretation here is of course: "Why does R think these numbers are equal".
Example:
6969277959563657216 == 6969277959563657217
[1] TRUE
More about this also on Wikipedia and several other places.
Edit: Here a SO posting about big integers long/bigint/decimal equivalent datatype in R

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

How come as.character(1) == as.numeric(1) is TRUE? [duplicate]

This question already has answers here:
Why does "one" < 2 equal FALSE in R?
(2 answers)
Why is the expression "1"==1 evaluating to TRUE? [duplicate]
(1 answer)
Closed 3 years ago.
Just like the title says, why does "1" == 1 is TRUE? What is the real reason behind this? Is R trying to be kind or is this something else? I was thinking since "1" (or any numbers it really doesn't matter) where read by R as a character it would automatically return FALSE if compare with as.numeric(1) or as.integer(1).
> as.character(1) == as.numeric(1)
[1] TRUE
or
> "1" == 1
[1] TRUE
I guess it is a simple question but I'd like to get an answer. Thank you.
According to ?==
For numerical and complex values, remember == and != do not allow for the finite representation of fractions, nor for rounding error. Using all.equal with identical is almost always preferable. S
In another paragraph, it is also written
x, y
atomic vectors, symbols, calls, or other objects for which methods have been written. If the two arguments are atomic vectors of different types, one is coerced to the type of the other, the (decreasing) order of precedence being character, complex, numeric, integer, logical and raw.
identical(as.character(1), as.numeric(1))
#[1] FALSE

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))

Why did I obtain wrong answer when using "=="? [duplicate]

This question already has answers here:
Why are these numbers not equal?
(6 answers)
Closed 9 years ago.
If I type:
x<-seq(0,20,.05)
x[30]
x[30]==1.45
Why do I obtain a False from the last line of code? What did I do wrong here?
This question has been asked a million times, albeit in different forms. This is due to floating point inaccuracy. Also here's another link on floating point errors you may want to catch up on!
Try this to first see what's going on:
x <- seq(0, 20, 0.5)
sprintf("%.20f", x[30]) # convert value to string with 20 decimal places
# [1] "14.50000000000000000000"
x[30] == 14.5
# [1] TRUE
All is well so far. Now, try this:
x <- seq(0, 20, 0.05)
sprintf("%.20f", x[30]) # convert value to string with 20 decimal places
# [1] "1.45000000000000017764"
x[30] == 1.45
# [1] FALSE
You can see that the machine is able to accurately represent this number only up to certain digits. Here, up to 15 digits or so. So, by directly comparing the results, you get of course a FALSE. Instead what you could do is to use all.equal which has a parameter for tolerance which equals .Machine$double.eps ^ 0.5. On my machine this evaluates to 1.490116e-08. This means if the absolute difference between the numbers x[30] and 1.45... is < this threshold, then all.equal evaluates this to TRUE.
all.equal(x[30], 1.45)
[1] TRUE
Another way of doing this is to explicitly check with a specific threshold (as #eddi's answer shows it).
This has to do with the fact that these are double's, and the correct way of comparing double's in any language is to do something like:
abs(x[30] - 1.45) < 1e-8 # or whatever precision you think is appropriate

Resources