Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a datatype "Decimal" in R?

I read data stored in the format DECIMAL from a MySQL-Table. I want to do calculations on those numbers within R.

I used to cast them to a numeri represaentation using as.numeric(), but the documentation says:

numeric is identical to double (and real).

But is there also a datatype Decimal in R? (Datatype without rounding errors,...)

Here a simple example for the problem with rounding errors:

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
like image 585
R_User Avatar asked Jun 06 '13 10:06

R_User


People also ask

Is decimal a data type in R?

Decimal values are referred to as numeric data types in R. This is the default working out data type. If you assign a decimal value for any variable x like given below, x will become a numeric type.

Which data type has a decimal?

The decimal data type is a machine-independent method that represents numbers of up to 32 significant digits, with valid values in the range 10 -129 - 10 +125. When you define a column with the DECIMAL( p ) data type, it has a total of p (< = 32) significant digits.


2 Answers

You could create your own:

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

Actually, some of the big number packages may work for this as well, since they use a similar representation....

like image 148
Ari B. Friedman Avatar answered Sep 20 '22 11:09

Ari B. Friedman


Similar approach to Ari answer but using integer64 class from bit64 package. Using big int as underlying data type for decimal is common practice in various applications that doesn't support decimal type natively.

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
like image 34
jangorecki Avatar answered Sep 19 '22 11:09

jangorecki