0

I would like to compare two vectors elementwise with the all.equal function. Strangely, these two comparisons give different results, and I wonder why it happens.

map2(c(1,1,0.7), c(1,1,0.6), all.equal, tolerance = 0.1, scale = 1)

[[1]]
[1] TRUE

[[2]]
[1] TRUE

[[3]]
[1] TRUE



map2(c(1,1,0.7), c(1,1,0.8), all.equal, tolerance = 0.1, scale = 1)
[[1]]
[1] TRUE

[[2]]
[1] TRUE

[[3]]
[1] "Mean absolute difference: 0.1"

Since the absolute difference between 0.7 and 0.8 and between 0.6 and 0.7 is the same, I expect to get T for both.

schd
  • 3
  • 1
  • Check: https://stackoverflow.com/questions/9508518/why-are-these-numbers-not-equal – Maël Mar 06 '23 at 10:41
  • `format(0.7 - 0.8, digits = 22); format(0.7 - 0.6, digits = 22)` – rawr Mar 06 '23 at 10:42
  • Maybe have also a look at [What is the correct/standard way to check if difference is smaller than machine precision?](https://stackoverflow.com/q/59229545/10488504). – GKi Mar 06 '23 at 10:54
  • Thanks everyone, it is clear! – schd Mar 06 '23 at 15:43

1 Answers1

0

This relates to floating point precision, described here, and there.

sprintf("%.54f", 0.7)
#[1] "0.699999999999999955591079014993738383054733276367187500"
sprintf("%.54f", 0.8)
#[1] "0.800000000000000044408920985006261616945266723632812500"

So the difference between both is actually > 0.1.


You can add a small tolerance to remedy this. Actually .Machine$double.eps^0.5 is the default tolerance for all.equal:

map2(c(1,1,0.7), c(1,1,0.8), all.equal, tolerance = 0.1 + .Machine$double.eps^0.5, scale = 1)

[[1]]
[1] TRUE

[[2]]
[1] TRUE

[[3]]
[1] TRUE
Maël
  • 45,206
  • 3
  • 29
  • 67