r-quantities / units

Measurement units for R
https://r-quantities.github.io/units
172 stars 27 forks source link

exp(log(x)) is not identity when unit has prefix #321

Closed dlill closed 2 years ago

dlill commented 2 years ago

Thanks for this amazing package! When a unit has a prefix, exp(log(x)) either throws an error (if the prefix modifies to values less than 1) or silently returns wrong values (when the prefix modifies to values greater than 1):

Errors

x <- 1
x <- units::set_units(x, "m", mode = "standard")
x <- units::set_units(x, "cm", mode = "standard")

exp(log(x)) 

Wrong values

x <- 1
x <- units::set_units(x, "m", mode = "standard")
x <- units::set_units(x, "km", mode = "standard")

stopifnot(identical(x, exp(log(x))))
x 
exp(log(x)) 

10^(log10(x))
units::set_units(10^(log10(x)), "km", model = "standard")
Enchufa2 commented 2 years ago

Thanks for the report. There's a special path for dealing with this kind of thing that we set up recently, and it seems there are some bugs with prefixes. I'll look into it.

One observation: all.equal must be used in these comparisons, instead of identical, because taking the exp of the log is necessarily going to lose some precision in some cases. For example:

x <- units::set_units(1000, "m", mode = "standard")
identical(x, exp(log(x)))
#> [1] FALSE
all.equal(x, exp(log(x)))
#> [1] TRUE
x 
#> 1000 [m]
exp(log(x)) 
#> 1000 [m]