How to deal with underflow in R? [duplicate] - r

This question already has answers here:
Dealing with very small numbers in R
(4 answers)
Closed 1 year ago.
I want to compute this number :
0.34911191 ^ 1157
I am using R programming language and it returns me 0 (this is an underflow problem). How I can fix it? Thanks.

Are you looking for something like this?
The CRAN package Brobdingnag has two vignettes explaining its use.
library(Brobdingnag)
x <- 1157 * log(0.34911191)
y <- as.brob(x)
exp(y)
#[1] +exp(-1217.6)
exp(y) < .Machine$double.neg.eps
#[1] TRUE

You can test the result using the Numerical Characteristics of the Machine (.Machine {base}), as shown below:
> 0.34911191 ^ 10 < .Machine$double.neg.eps
[1] FALSE
> 0.34911191 ^ 1157 < .Machine$double.neg.eps
[1] TRUE
double.neg.eps is a small positive floating-point number x such that 1 - x != 1.

Related

R factorial() is not yielding the correct result [duplicate]

This question already has answers here:
Why are these numbers not equal?
(6 answers)
Closed 3 days ago.
I am trying to calculate the factorial of 52 in R. Astonishingly, I am getting contradicting results.
aaa<-1*2*3*4*5*6*7*8*9*10*11*12*13*14*15*16*17*18*19*20*21*22*23*24*25*26*27*28*29*30*31*32*33*34*35*36*37*38*39*40*41*42*43*44*45*46*47*48*49*50*51*52
bbb<-factorial(52)
aaa
[1] 80658175170943876845634591553351679477960544579306048386139594686464
bbb
[1] 80658175170944942408940349866698506766127860028660283290685487972352
aaa==bbb #False
What am I doing wrong?
This is a well known problem in computing with large numbers; R uses double-precision floating-point, the precision of which may vary by machine. Thats why you are getting multiple results across methods (including the online calculator in your comments). If you want to change your precision (in bits), one option is to use the Rmpfr package:
Rmpfr::mpfr(factorial(52),
6) # six bits
#1 'mpfr' number of precision 6 bits
#[1] 8.09e+67
Rmpfr::mpfr(factorial(52),
8) # eight bits
#1 'mpfr' number of precision 8 bits
#[1] 8.046e+67
This will allow you to obtain a result with the same value:
x <-Rmpfr::mpfr(1*2*3*4*5*6*7*8*9*10*11*12*13*14*15*16*17*18*19*20*21*22*23*24*25*26*27*28*29*30*31*32*33*34*35*36*37*38*39*40*41*42*43*44*45*46*47*48*49*50*51*52,
8)
y <- Rmpfr::mpfr(factorial(52),
8)
x == y
#[1] TRUE

Use Remainders of modulo operator in R for logical comparisons [duplicate]

This question already has answers here:
Why are these numbers not equal?
(6 answers)
Is floating point math broken?
(31 answers)
Closed 3 years ago.
I noticed recently a weird behavior when I wanted to differentiate a variable by the remainder.
x <- ifelse(48.002 %% 1 == 0.002, 1, 0)
However, testing the logic operation above showed this is not true.
48.002 %% 1 == 0.002
[1] FALSE
While if I use >= instead of ==, it could identify correctly:
48.002 %% 1 >= 0.002
[1] TRUE
48.001 %% 1 >= 0.002
[1] FALSE
Could someone please help me understand why this is happening? Thanks.

R - Equivalent inputs resulting in different outputs for a sequence [duplicate]

This question already has an answer here:
Why does the vector gets expanded in the loop
(1 answer)
Closed 6 years ago.
I am running into some behaviour with R that I find confusing. Does anyone have any insight into what is going on here?
Define two objects
i <- 5
nr <- 10
So i + 2 and nr + 1
> i+2
[1] 7
> nr+1
[1] 11
So to create a sequence from 7 to 11 I could do this:
7:11
But my question why does this not produce the same result?
i+2:nr+1
We already established above that it's input numbers are equivalent. Obviously I'm missing something here but I just don't know what it is.
You have just discovered the prime R gotcha, namely: 1:n-1 produces the sequence 0, 1, 2, ..., n-1.
To obtain what you desire, wrap the expressions in brackets:
1:(n-1)
or use
seq.int(1, n-1)
The reason for the issue is operator precedence - ?Syntax`

R get wrong result for a sum [duplicate]

This question already has answers here:
Why are these numbers not equal?
(6 answers)
Closed 9 years ago.
I am experiencing something weird with R recently. It can't get a sum write (even a simple one), I looked for any kind of precision issue but it did not seem it was the problem.
Any idea what could lead to that ?
> 0.1+0.2-0.4
Returns
> [1] -0.099999999999999977796
The answers to the question this will be closed as a duplicate of explains what is going on. But for a quick little thing hopefully this helps:
> options(digits = 22)
> .1 + .2 - 0.4
[1] -0.09999999999999997779554
> 0.1
[1] 0.1000000000000000055511
> 0.2
[1] 0.2000000000000000111022
> 0.4
[1] 0.4000000000000000222045
You can't represent 0.1 perfectly on a computer. It works with binary so only powers of 2 can be perfectly represented in decimal form. Some more examples:
> 1/2^2
[1] 0.25
> 1/2^3
[1] 0.125
> 1/2^4
[1] 0.0625
> 1/3
[1] 0.3333333333333333148296
You can set the display precision with something like
options(digits=10)
But this doesn't affect the actual precision of the calculation - most non-integer-values (such as 0.1) cannot be represented exactly in floating point arithmetic.
See here for an introduction into floating point arithmetic:
http://download.oracle.com/docs/cd/E19957-01/806-3568/ncg_goldberg.html

First circle of R hell. 0.1 != 0.3/3 [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Numeric comparison difficulty in R
Hello All,
According to "R Inferno" paper. I'm right now in the first circle of R hell. This is where pagans expect 0.1 == 0.3/3. Paper recommends using all.equal function for such cases, however I need to check ">=" or "<=" conditions. With current example on of them fail:
> .1 >= .3/3
[1] TRUE
> .1 <= .3/3
[1] FALSE
Is there a similar function to all.equal that checks inequalities?
Thank you,
Ilya
The main test of all.equal is whether abs(x-y) < tolerance for some values x and y and some small tolerance. Equivalent inequality tests would check:
x <= y: x-y < tolerance
x < y: x-y < -tolerance
x >= y: x-y > -tolerance
x > y: x-y > tolerance
See these questions:
In R, what is the difference between these two?
Numeric comparison difficulty in R
Generally speaking, you can deal with this by including a tolerance level as per the second link above.
Please see the R FAQ entry Why doesn't R think these numbers are equal and the references therein.
You could try judicious use of zapsmall() which seems to give the behavior you are looking for. I don't know if this works in all situations. e.g.,
.1 >= zapsmall(.3/3)
[1] TRUE
> .1 <= zapsmall(.3/3)
[1] TRUE

Resources