Существует ли тип данных "Десятичный" в R? - программирование
Подтвердить что ты не робот

Существует ли тип данных "Десятичный" в R?

Я читаю данные, хранящиеся в формате DECIMAL из MySQL-таблицы. Я хочу делать вычисления на этих числах внутри R.

Я использовал их для численного представления с помощью as.numeric(), но в документации говорится:

числовое значение идентично двойному (и реальному).

Но существует ли также тип данных Decimal в R? (Тип данных без ошибок округления,...)

Вот простой пример проблемы с ошибками округления:

numbersStrings = c("0.1", "0.9")
numbersNumeric = as.numeric(numbersStrings)
numbersMirror  = c(numbersNumeric, 1-numbersNumeric)

str(numbersMirror)

numbersMirror
unique(numbersMirror)  # has two times 0.1 ...

sprintf("%.25f", numbersMirror)
sprintf("%.25f", unique(numbersMirror))  # ... because there was a rounding error
4b9b3361

Ответ 1

Вы можете создать свой собственный:

d <- structure( list(i=589L,exp=2L), class="decimal" )
print.decimal <- function( x, ...) print( x$i * 10^(-x$exp) )
> d
[1] 5.89

Собственно, некоторые из пакетов большого числа могут работать и для этого, так как они используют аналогичное представление....

Ответ 2

Аналогичный подход к ответу Ари, но с использованием класса integer64 из пакета bit64. Использование большого int в качестве базового типа данных для десятичного числа является обычной практикой в ​​различных приложениях, которые не поддерживают десятичный тип изначально.

library(bit64)

as.decimal = function(x, p=2L) structure(as.integer64(x*10^p), class="decimal", precision=p)
print.decimal = function(x) print(as.double(x))
as.integer64.decimal = function(x) structure(x, class="integer64", precision=NULL) # this should not be exported
as.double.decimal = function(x) as.integer64(x)/(10^attr(x, "precision"))
is.decimal = function(x) inherits(x, "decimal")
"==.decimal" = function(e1, e2) `==`(as.integer64(e1), as.integer64(e2))
"+.decimal" = function(e1, e2) `+`(as.integer64(e1), as.integer64(e2))

d = as.decimal(12.69)
is.decimal(d)
#[1] TRUE
print(d)
#[1] 12.69
as.double(d)
#[1] 12.69
d + as.decimal(0.9)
#[1] 13.59
0.1 + 0.2 == 0.3
#[1] FALSE
as.decimal(0.1) + as.decimal(0.2) == as.decimal(0.3)
#[1] TRUE