-2

The first line gives me 0.1 and the second line gives me 0.10000000000000001. Why does this happen? Is rounding a viable solution? Or is there a more precise solution? I would expect the first line to be "0.1" and the second line to be 0.1.

print(input[[nm]][[i+j]])
print(as.numeric(input[[nm]][[i+j]]))
[1] "0.1"
[1] 0.10000000000000001
Ben Bolker
  • 211,554
  • 25
  • 370
  • 453
X L
  • 27
  • 5

1 Answers1

2

This is controlled by the digits setting in your options. options("digits") will tell you the current value, options(digits=8) (for example) will set the value. The "extra" values at the end are due to floating-point error (see Chapter 1 of The R Inferno or search Stack Overflow for question about floating point, e.g. this one. (Note that this doesn't change the underlying value, just the way it is printed.)

It's impossible to express 0.1 exactly in binary floating-point representation.

Here's what gets printed with different digits settings (it looks like you must have digits set to 17 ...)

x <- "0.1"
for (i in 1:20) print(c(i,as.numeric(x)), digits=i)
[1] 1.0 0.1
[1] 2.0 0.1
[1] 3.0 0.1
[1] 4.0 0.1
[1] 5.0 0.1
[1] 6.0 0.1
[1] 7.0 0.1
[1] 8.0 0.1
[1] 9.0 0.1
[1] 10.0  0.1
[1] 11.0  0.1
[1] 12.0  0.1
[1] 13.0  0.1
[1] 14.0  0.1
[1] 15.0  0.1
[1] 16.0  0.1
[1] 17.00000000000000000  0.10000000000000001
[1] 18.000000000000000000  0.100000000000000006
[1] 19.0000000000000000000  0.1000000000000000056
[1] 20.00000000000000000000  0.10000000000000000555

As you suggest in your comment, you can use all.equal() to test for approximate equality. as.numeric(x)==0.1 is TRUE, as is all.equal(as.numeric(x),0.1). You can adjust the tolerance of all.equal():

z1 <- 0.1
z2 <- z1 + 1e-14
all.equal(z1,z2) ## TRUE
all.equal(z1,z2,tolerance=1e-15)
## [1] "Mean relative difference: 1.000589e-13"
isTRUE(all.equal(z1,z2,tolerance=1e-15)) ## FALSE
Ben Bolker
  • 211,554
  • 25
  • 370
  • 453
  • Ya I understand that, thanks. But then how do I test for equality? == is returning false and all.equal is returning true even if they are quite far from being equal – X L Jan 22 '21 at 15:45
  • 2
    I've tried to answer your second question. (Please note that my answer *does* answer the question you actually asked, I think ...) For new questions, it's best to post a brand-new question, otherwise you risk the original turning into a [chameleon question](https://meta.stackexchange.com/questions/43478/exit-strategies-for-chameleon-questions) ... – Ben Bolker Jan 22 '21 at 15:56