Get exact values of floats in R? - r

I want to get all different float values in a sample:
unique(c(0.100000000002, 0.100000000003))
But this only returns two times 0.1 which are not unique values:
[1] 0.1 0.1
How can I list the exact values that are saved?

That's just R's default printing limit of 7 significant figures. To see the true underlying values:
print(unique(c(0.100000000002, 0.100000000003), digits=15)
To change the default behaviour, see ?options; you want something like options(digits=15).

Use sprintf...
x <- unique(c(0.100000000002, 0.100000000003))
sprintf("%.20f", x)
#[1] "0.10000000000200000294" "0.10000000000299999470"
From the help page for sprintf...
f
Double precision value, in “fixed point” decimal notation of the
form "[-]mmm.ddd". The number of decimal places ("d") is specified by
the precision: the default is 6; a precision of 0 suppresses the
decimal point. Non-finite values are converted to NA, NaN or (perhaps
a sign followed by) Inf.

Here you go
options(digits=14)
unique(c(0.100000000002, 0.100000000003))

Related

Can as.numeric(as.character(x)), where x is originally a numeric, ever change x?

I am wondering if converting numerics to characters and then back again in R can ever change the number? For example, does as.character round off numerics after a certain amount of decimal places (if so, how many)?
#jogo thanks for the suggestion :)
Here is the comment as an answer:
From ?as.character():
as.character represents real and complex numbers to 15 significant
digits (technically the compiler's setting of the ISO C constant
DBL_DIG, which will be 15 on machines supporting IEC60559 arithmetic
according to the C99 standard). This ensures that all the digits in
the result will be reliable (and not the result of representation
error), but does mean that conversion to character and back to numeric
may change the number. If you want to convert numbers to character
with the maximum possible precision, use format.
So yes it does change the number if you have more than 15 significant digits. See:
> as.character(1.000000000000001) # more than 15 significant digits
[1] "1"
> as.character(1.00000000000001) # less than 15 significant digits
[1] "1.00000000000001"
Here are some other examples:
y <- as.numeric(as.character(pi))
identical(y, pi) ### gives FALSE
or
x <- 1/7
y <- as.numeric(as.character(x))
x-y
or
as.numeric(as.character(.Machine$double.xmax)) ## result: Inf

How to round a value that contains exponent?

Using below code I'm attempting to round a value to 2 decimal places. This works as expected when exponent is not contained in value. But when exponent is contained as in :
> toround <- 1.1234e-2
> round(toround , 2)
Returned is :
[1] 0.01
When I'm expecting :
[1] 1.12e-2
How to use round function for exponent ?
Update :
> ?signif
> ?round
Appear to return same help documentation so why does signif function (thanks to answer by Evan Weissburg) work for exponent but round does not ?
Since it's in exponential notation already, you know that rounding to a decimal place is the same as rounding to significant figures + 1; rounding to the hundredths place is just getting the first three significant figures.
> signif(1.326135235e-09, 3)
[1] 1.12e-2
Of course, the round function is also going to give you the correct result.
1.1234e-2 = 0.011234, so 0.01 is a perfectly correct result rounded to two decimal places. Decimal places != significant figures.

rounding of digits

I'm having troubles with
set.seed(1)
sum(abs(rnorm(100)))
set.seed(1)
cumsum(abs(rnorm(100)))
Why does the value of the sum differ from the last value of the cumulative sum with the cumulative sum preserving the all decimal digits and sum rounding 1 digit off.
Also note that this really really is about how values are printed i.e. presented. This does not change the values themselves, e.g. ...
set.seed(1)
d1 <- sum(abs(rnorm(100)))
set.seed(1)
d2 <- cumsum(abs(rnorm(100)))
(d1 == d2)[100]
## [1] TRUE
This is a consequence of the way R prints atomic vectors.
With the default digits option set to 7 as you likely have, any value between -1 and 1 will print with seven decimal places. Because of the way R prints atomic vectors, all other values in the vector will also have seven decimal places. Furthermore, a value of .6264538 with digits option set to 7 must print with eight digits (0.6264538) because it must have a leading zero. There are two of these values in your rnorm() vector.
If you look at cumsum(abs(rnorm(100)))[100] alone and you can see the difference (actually it becomes the same as printed value as sum(abs(rnorm(100))), although not exactly the same value).
sum(abs(rnorm(100)))
# [1] 71.67207
cumsum(abs(rnorm(100)))[100]
# [1] 71.67207
Notice that both of these values have seven digits. Probably the most basic example of this I can think of is as follows
0.123456789
#[1] 0.1234568
1.123456789
#[1] 1.123457
11.123456789
# [1] 11.12346
## and so on ...

unable to get desired precision of the output from division of 2 integers in R

Iam dividing two numbers in R. The numerator is a big integer ( ranges in millions) divided by a 13.00001
It is taking 13.000001 as 13 and the output that comes is limited to only 1 decimal place.
I require the output to be uptil 2 decimal places which is not happening.
I tried round, format and as.numeric but it is fruitless
round is not giving anything (round(divison,1)
format(nsmall=2) makes it upto 2 decimal places but converts it into character
as.numeric reconverts it from character but the 2 decimal places are replaced by 1 decimal place
Is there any way that I can get 2 decimal places when I divide an integer with a number like 13.000001?
Be careful not to confuse output with internal precision:
x <- 13e7/13.000001
sprintf("%10.20f",x)
#[1] "9999999.23076928965747356415"
sprintf("%10.10f",x*13)
#[1] "129999990.0000007600"
sprintf("%10.10f",x*13.000001)
#[1] "129999999.9999999851"
Differences to the expected output are due to the limited floating point precision.

How do you cast a double to an integer in R?

My question is: Suppose you have computed an algorithm that gives the number of iterations and you would like to print the number of iterations out. But the output always many decimal places, like the following:
64.00000000
Is it possible to get an integer by doing type casting in R ? How would you do it ??
There are some gotchas in coercing to integer mode. Presumably you have a variety of numbers in some structure. If you are working with a matrix, then the print routine will display all the numbers at the same precision. However, you can change that level. If you have calculated this result with an arithmetic process it may be actually less than 64 bit display as that value.
> 64.00000000-.00000099999
[1] 64
> 64.00000000-.0000099999
[1] 63.99999
So assuming you want all the values in whatever structure this is part of, to be displayed as integers, the safest would be:
round(64.000000, 0)
... since this could happen, otherwise.
> as.integer(64.00000000-.00000000009)
[1] 63
The other gotcha is that the range of value for integers is considerably less than the range of floating point numbers.
The function is.integer can be used to test for integer mode.
is.integer(3)
[1] FALSE
is.integer(3L)
[1] TRUE
Neither round nor trunc will return a vector in integer mode:
is.integer(trunc(3.4))
[1] FALSE
Instead of trying to convert the output into an integer, find out why it is not an integer in the first place, and fix it there.
Did you initialize it as an integer, e.g. num.iterations <- 0L or num.iterations <- integer(1) or did you make the mistake of setting it to 0 (a numeric)?
When you incremented it, did you add 1 (a numeric) or 1L (an integer)?
If you are not sure, go through your code and check your variable's type using the class function.
Fixing the problem at the root could save you a lot of trouble down the line. It could also make your code more efficient as numerous operations are faster on integers than numerics (an example).
The function as.integer() truncate the number up to 0 order, so you must add a 0.5 to get a proper approx
dd<-64.00000000
as.integer(dd+0.5)
If you have a numeric matrix you wish to coerce to an integer matrix (e.g., you are creating a set of dummy variables from a factor), as.integer(matrix_object) will coerce the matrix to a vector, which is not what you want. Instead, you can use storage.mode(matrix_object) <- "integer" to maintain the matrix form.

Resources