-
Notifications
You must be signed in to change notification settings - Fork 0
Description
It's hard/impossible to derive decimal places from a double without implementing arbitrary-precision decimal numbers (or similar) (although I just tried Rmpfr and bignum and it didn't seem to actually make a difference for number of decimal places). I think the function needs to come with some kind of warning or documentation caveats to the user about the issues surrounding counting decimal places in standard floating-point types.
e.g.,:
The number of decimals that can be counted depends on precision limits & finite precision arithmetic, typically 15/16 sig. digits.
x <- c(
123456.123456789, # correct
1234567.123456789, # all others 'fail'
12345678.123456789,
999999999999999.12
)
decimal_places(x)
[1] 9 8 7 0
as.character(x)
[1] "123456.123456789" "1234567.12345679" "12345678.1234568" "999999999999999"
R's scientific printing can also affect the character conversion:
x <- c(100000000000000.1, 0.0000001)
decimal_places(x)
[1] 0 0
as.character(x)
[1] "1e+14" "1e-07"
format() can be an option but has other issues:
format(0.0000001, scientific = FALSE) # works
[1] "0.0000001"
format(100000000000000.1, scientific = FALSE) # 'fails'
[1] "100000000000000"
# 'fails' where as.character() would work
format(1000000.1, scientific = FALSE)
[1] "1000000"
# highlights problem with floating point representation
format(c(100000000000000.1, 0.0000001), scientific = FALSE)
[1] "100000000000000.0937500" " 0.0000001"
Alternatively, counter this by ensuring that if the decimal places check is asked for, the data for that check is read in as string, and then no floating-point representation is made and everything is great! Just have to be careful about the data storage in the first place as numeric excel data is auto-rounded to 15... but then that would be fine with this function if the data creator was happy?
q <- readxl::read_excel(r"[D:\Misc\data.checker\test_long_numeric_input.xlsx]", col_names = FALSE)
# if stored as text in the .xlsx
q$...1
[1] "1.12345678911234567"
q$...2
[1] "12345678911234.578"
as.character(1.12345678911234567)
[1] "1.12345678911235"