Home > Software design >  printed value for high numbers is wronger than it should?
printed value for high numbers is wronger than it should?

Time:07-08

When printing a high number in R I expect to see a rounded value due to floating point magic. Indeed :

options(scipen = 999)
x <- 10000000000000000000000000
x
#> [1]  9999999999999998758486016

However I expected that this rounded number would be rounded to itself, and it appears it isn't

x ==  9999999999999998758486016
#> [1] FALSE

9999999999999998758486016
#> [1]  9999999999999996611002368

I found manually the min number that rounds to the original rounded value

x ==  9999999999999998799999999
#> [1] FALSE

9999999999999998799999999
#> [1]  9999999999999996611002368

x ==  9999999999999998800000000
#> [1] TRUE

9999999999999998800000000
#> [1]  9999999999999998758486016

While an explanation would be appreciated, I have a practical issue. I'd like to design a faithful dput() equivalent that would work with any number.

The constraint to satisfy is : x == as.numeric(my_deparser(x))

If mydeparser() could return "9999999999999998800000000" for the above for instance I'd be happy, because

10000000000000000000000000 == as.numeric("9999999999999998800000000")
#> [1] TRUE

I've tried format(), dput(), deparse() with no luck.

How can I achieve this ?

CodePudding user response:

An option is to use a package like gmp or Rmpfr. Below a few examples with package gmp.

library(gmp)
#> 
#> Attaching package: 'gmp'
#> The following objects are masked from 'package:base':
#> 
#>     %*%, apply, crossprod, matrix, tcrossprod

x <- as.bigz("10000000000000000000000000")
x
#> Big Integer ('bigz') :
#> [1] 10000000000000000000000000

x   1
#> Big Integer ('bigz') :
#> [1] 10000000000000000000000001
x * x
#> Big Integer ('bigz') :
#> [1] 100000000000000000000000000000000000000000000000000

Created on 2022-07-07 by the reprex package (v2.0.1)

CodePudding user response:

I believe that the scipen option has to do with how values are printed, not how they are stored, so when you do:

x <- 10000000000000000000000000

The value is actually stored as 10000000000000000000000000, even if it prints as something else. So

x == 10000000000000000000000000

should return TRUE.

  • Related