0

Here's the codes:

2.9999999999999948933990 > 2.999999999999994893399
[1] TRUE
"20" > 2.999999999999994893399
[1] TRUE
"20" > 2.9999999999999948933990
[1] FALSE
"200" > 2.999999999999994893399
[1] TRUE
"200" > 2.9999999999999948933990
[1] FALSE
"20" > "200"
[1] FALSE
"20" < "200"
[1] TRUE

My mind is just boomed. Can anyone explain why adding a 0 matters? Also, which exact numbers "20" and "200" equal with?

neilfws
  • 32,751
  • 5
  • 50
  • 63
  • 1
    strings are compared by string comparison. Which comes first in the dictionary, "ba" or "baa" ? – Ben Bolker Jan 27 '22 at 03:47
  • I think this is a situation that confuses many R users - even experienced users - and I thought the example given was a good one. I would not mind a fuller explanation of the observed behaviour. – neilfws Jan 27 '22 at 04:50

2 Answers2

3

According to help("Comparison"), numeric values are converted to character strings (for the comparison) if you compare them to a character string. Adding the 0 matters due to accuracy of floating point numbers.

In help("as.character") it is documented that

as.character represents real and complex numbers to 15 significant digits

Now compare this:

sprintf("%.16f", 2.999999999999994893399)
#[1] "2.9999999999999947"
sprintf("%.16f", 2.9999999999999948933990)
#[1] "2.9999999999999951"

as.character(2.999999999999994893399)
#[1] "2.99999999999999"
as.character(2.9999999999999948933990)
#[1] "3"
Roland
  • 127,288
  • 10
  • 191
  • 288
0

Part of the problem is that 2.999999999999994893399 and 2.9999999999999948933990 are not parsed as the same number. The reason for this is likely the parsing algorithm that R uses. I believe it goes something like this:

When you see a number containing a decimal point, ignore the decimal and read the number as an integer, then divide by the appropriate power of 10.

So 2.999999999999994893399 is read as 2999999999999994893399 and divided by 10^21. But 2999999999999994893399 is too big to represent exactly, so it becomes 2999999999999994757120 after reading, and that becomes 2.9999999999999946709 after the division (since 10^21 can't be stored exactly either).

On the other hand, 2.9999999999999948933990 is read as 29999999999999948933990 and divided by 10^22. Rounding is different, because the number is 10 times bigger: the integer becomes 29999999999999949668352 and after division it is 2.999999999999995115.

Some of the numbers I show might be different on your system: most of this is handled at a very low level, and could be different depending on the system library and hardware.

user2554330
  • 37,248
  • 4
  • 43
  • 90