Есть ли тип данных «Десятичный» в 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
 Ferdinand.kraft10 июн. 2013 г., 20:57
@DWin,Rmpfr может быть установлен для использования 64 бит. Я написал "произвольная точность " но я имел ввидумножественная точность ", :-) Этого не добиться вобычный R " с помощьюdoubleтолько с
 Ferdinand.kraft06 июн. 2013 г., 22:30
Это может быть полезно:cran.r-project.org/web/packages/Rmpfr/index.html Это's библиотека для выполнения операций с плавающей точкой произвольной точности в R.
 John Garreth10 июн. 2013 г., 12:48
Хороший пример. Я решил аналогичную проблему с помощьюtable() (здесь вы можете использоватьtable(numbersMirror)). стол, кажется, округляет числа. У меня нет подробностей о том, как это округляется, но для вашего примера это работает. В любом случае: десятичный тип данных должен быть более точным. (конечно только для - / + операций). @DWin: я думаю, ты имел в видуround() вместо усечения.
 42-10 июн. 2013 г., 21:17
Это'будет PITA для управления, так как вам нужно будет принести "номера» в качестве символьного представления из MySQL, а затем преобразовать в Rmpfr и затем преобразовать обратно в символ, а затем написать код в MySQL для преобразования символов в DECIMAL.
 42-07 июн. 2013 г., 04:32
В документации MySQL ясно, что DECIMAL не является произвольной точностью. Он допускает больше цифр (64), чем может быть представлено вдвойной» (53). Также ясно, что усечение ожидается, если цифры справа от десятичной точки превышают выбранный предел. Я подозреваю, что усечение до определенного предела для двойников может удовлетворить большинство потребностей.

Ответы на вопрос(2)

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

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

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

d 
 Ari B. Friedman06 июн. 2013 г., 15:38
@Henrik Я согласен. Это'Конечно, это боль. Окупаемость точности должна стоить того для вашего конкретного приложения :-)
 Ben Bolker16 июн. 2013 г., 17:35
 Henrik06 июн. 2013 г., 14:34
и тогда вам нужно только написать методы для основных арифметических операций и неосновных, которые вам нужны ... (но, отличный ответ)

Ваш ответ на вопрос