Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Very small numbers print as Inf.e-324 #615

Closed
ccsarapas opened this issue Oct 19, 2022 · 6 comments · Fixed by #619
Closed

Very small numbers print as Inf.e-324 #615

ccsarapas opened this issue Oct 19, 2022 · 6 comments · Fixed by #619

Comments

@ccsarapas
Copy link

Reprex:

library(pillar)

pillar(4e-324)
#> <pillar>
#>     <dbl>
#> Inf.e-324

This looks similar to tidyverse/tibble#377, which was previously closed at d3e1384.

@bbolker
Copy link

bbolker commented Oct 19, 2022

I dug in a little bit here: https://stackoverflow.com/a/74131254/190277 but didn't make it all the way to the bottom ...

@rikivillalba
Copy link

rikivillalba commented Oct 19, 2022

Problem appears to be in the function safe_divide_10_to <- function(x, y) { given in R 4.940656e-324 /(10^-324) gives Inf.

@bbolker
Copy link

bbolker commented Oct 19, 2022

It's pretty funny that the source code is

safe_divide_10_to <- function(x, y) {
  # Computes x / 10^y in a robust way

  x / (10^y)
}

Did someone mean to implement a robust division by 10^y and forget? Should this be exp(log(x) - y*log(10)) ? Is this called often enough that the computational cost is a problem? (M_LN10 is defined in C/C++ header files ...)

In this particular case the solution to tidyverse/tibble#377 isn't useful, as x*10^(-y) and x/10^y are both Inf ...

@krlmlr
Copy link
Member

krlmlr commented Oct 20, 2022

Thanks, good catch.

Would 10 ^ (log10(x) - y) also work? Or is 10 ^ . just a variant of exp() under the hood?

Is this a case of comment rot? I don't remember what happened here off the top of my head.

@bbolker
Copy link

bbolker commented Oct 20, 2022

Yes, that will work. Speed is hardly different (note units are in nanoseconds ...)

x <- 4.94e-324
y <- -324
library(microbenchmark)
l10 <- log(10)  ## precompute
f1 <- function(x,y) exp(log(x)-y*l10)
f2 <- function(x,y) 10^(log10(x)-y)
all.equal(f1(x,y), f2(x,y))
mb <- microbenchmark(f1(x,y), f2(x,y), times = 10000L)

Unit: nanoseconds
     expr min  lq     mean median  uq  max neval cld
 f1(x, y) 641 671 712.3680    691 721 6222 10000  a 
 f2(x, y) 661 691 740.3547    711 742 9337 10000   b

@rikivillalba
Copy link

rikivillalba commented Oct 20, 2022

This also worked for me https://stackoverflow.com/a/74132326/6912817 in Windows / Intel(R) Core(TM) i5-8350U CPU @ 1.70GHz

library(tibble)

print(tibble(x = c(4e-300, 4e-324, 4e324, 10, -10, 4e-350)))
#> # A tibble: 6 × 1
#>           x
#>       <dbl>
#> 1   4 e-300
#> 2 Inf.e-324
#> 3 Inf      
#> 4   1 e+  1
#> 5  -1 e+  1
#> 6   0

assignInNamespace("safe_divide_10_to", 
                  function(x,y) 10^(log10(x) - y), "pillar")

print(tibble(x = c(4e-300, 4e-324, 4e324, 10, -10, 4e-350)))
#> # A tibble: 6 × 1
#>             x
#>         <dbl>
#> 1   4   e-300
#> 2   4.94e-324
#> 3 Inf        
#> 4   1   e+  1
#> 5  -1   e+  1
#> 6   0

@github-actions github-actions bot locked and limited conversation to collaborators Oct 31, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants