PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Wednesday, August 10, 2022

[FIXED] Why does as.numeric add decimal places when converting a character?

 August 10, 2022     decimal, precision, r, rounding     No comments   

Issue

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

Solution

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


Answered By - Ben Bolker
Answer Checked By - Cary Denson (PHPFixing Admin)
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing