Minimum evaluatable scientific value? - r

Does R store the smallest possibly representable scientific value?
To clarify: on my current machine:
>1e-300
[1] 1e-300
While
>1e-400
[1] 0
Through trial and error I know it is somewhere around the e-324 mark on my machine (where it also starts losing precision).
>1e-324
[1] 0
>5e-324
[1] 4.940656e-324
I've searched through the .Machine list and none of the values it stores contain either the value, or the exponent I'm looking for.
Edit:
Linked threads on the side indicate that this should be .Machine$double.eps, which is 2.220446e-16. Clearly this is no longer the case?

The smallest normalised is double.xmin, as described in this page. The Wikipedia entry is very interesting and has the subnormal limit which is 2^-1074, which is approximately 4.9406564584124654 x 10^-324 (from Wikipedia as Ben Bolker mentioned in the comments). Your output in R is matching this value.
double.epsilon is not what you think. It is the smallest number you can add to 1 such as you obtain a number which will be not recognised as 1.
I suggest you read about how the double are stored in memory and the basics of double operations. Once you understand how a double is stored the lower limit is obvious.

The accepted answer remains correct for base R, but using the package Rmpfr enables arbitrary precision. Example:
First, note issue in base R:
> p <- c("5e-600","2e-324","3e-324","4e-324", "5e-324","6e-324","7.1e-324","8e-324")
> as.numeric(p)
[1] 0.000000e+00 0.000000e+00 4.940656e-324 4.940656e-324 4.940656e-324 4.940656e-324
[7] 4.940656e-324 9.881313e-324
Observe that as we near the limit the precision is an issue and all values are 4.940656e-324.
Now use mpfr function from 'Rmpfr` package to cast the strings as floats:
> library(Rmpfr)
> .N <- function(.) mpfr(., precBits = 20)
> .N(p)
8 'mpfr' numbers of precision 20 bits
[1] 5.0000007e-600 2.00000e-324 2.9999979e-324 4.00000e-324 4.9999966e-324 5.9999959e-324
[7] 7.09999e-324 8.00000e-324

Related

Large exponent values in R with 'Rmpfr'

I am trying to calculate the value of exp(1000) or more in R. I looked at the solution provided in Calculate the exponentials of big negative value and followed it to replicate the code for negative values first, but I have the following output.
a <- mpfr(exp(-1000),precBits = 64)
a
1 'mpfr' number of precision 64 bits
[1] 0
I do not understand why my output would be different from the provided solution. I understand this particular solution is for negative values and that I am looking for positive exponents. Regardless, it should work for both ways.
You need to convert to extended precision before you exponentiate, otherwise R will try to compute exp(-1000) with its usual precision and underflow will occur (as you found out).
> a <- exp(mpfr(-1000, precBits = 64))
> a
1 'mpfr' number of precision 64 bits
[1] 5.07595889754945676548e-435

Numerical problems with qnorm

I'm having a numeric issue using qnorm(psn()). The problem is numeric.
Firstly, the Skew-Normal CDF round the result, since psn(9) is not 1:
library(sn)
psn(9)
#[1] 1
then
qnorm(psn(9))
#[1] Inf
And see that:
qnorm(.9999999999999999)
#[1] 8.209536
qnorm(.99999999999999999)
#[1] Inf
note that 8.209536 is not that big, so this rounding is very imprecise.
Then, my final problem is the calculation of qnorm(psn()), that is part of my Copula density. Any hint on how can I avoid these numerical problems?
(This is not a resolution to your dilemma, more of an explanation of why I think you're seeing this and perhaps not likely to find an easy solution.)
I think this is getting into the realm where normal floating-point precision isn't going to work for you. For instance, doing the inverse of your function:
options(digits=22)
pnorm(8.209536)
# [1] 0.99999999999999989
pnorm(8.209536) - 1
# [1] -1.1102230246251565e-16
which is very close to
.Machine$double.eps
# [1] 2.2204460492503131e-16
which, according to ?.Machine, is
double.eps: the smallest positive floating-point number 'x' such that
'1 + x != 1'. It equals 'double.base ^ ulp.digits' if either
'double.base' is 2 or 'double.rounding' is 0; otherwise, it
is '(double.base ^ double.ulp.digits) / 2'. Normally
'2.220446e-16'.
It might be possible to translate what you need into higher-precision using auxiliary packages like gmp or Rmpfr. (I don't know if they support qnorm-like operations.)

Square root of a number to 100 decimal places

How can I get the square root for a number to 100 decimal places in R?
I've looked into the gmp and the Rmpfr packages. I can't figure out how I would use them for square roots, (pow.bigz(2,0.5)=1)
but even if I did, I'm not sure how accurate it would be, since I've found that after about 25 decimal places, the digits aren't reliable
eg
mpfr(1/3,400)
# 1 'mpfr' number of precision 400 bits
# [1] 0.333333333333333314829616256247390992939472198486328125
and
as.bigz(1e50/3)
# Big Integer ('bigz') :
# [1] 33333333333333337607355566542238210608487100055552
The question is computing one third prior to mpfr so it has already lost precision by the time mpfr sees it. Do it this way:
mpfr(1, 400)/3

How to get the product of all the elements of a matrix with exact decimal points without rounding off in R?

I previously used the prod() function in R that can give me the product, and it works fine for big numbers. The numbers I have are too small like 1.294528e-07 and once I take the product it gives me a 0. How can I get the accurate product with exact decimal numbers?
This sounds like a job for Rmpfr:
x <- 1.294528e-07;
x^100;
## [1] 0
library('Rmpfr');
mpfr200 <- function(...) mpfr(...,precBits=200);
x <- mpfr200(1.294528e-07);
x^100;
## 1 'mpfr' number of precision 200 bits
## [1] 1.6260909947893069252110098843324246495136887016336218206204661e-689
Or you could try using big rationals from gmp, although that can get unwieldy fast:
library('gmp');
x <- as.bigq(1.294528e-07);
x^100;
## Big Rational ('bigq') :
## [1] 863201774730415899361077141424209396921125795515936990572548766128423810485376236957138978501283812494839104247698243918794530436552717763753923415271480284747830193402522833445368586578235815336302329397252055448087703163456038666698935354732741208048881276922439385153961853551463063865863458552423073323374618023089542368149617965922293453325011050815707644365808660423522776994133587512616070446174486428153909409377712433145387919387175172482342168167092570331925560436171324785600650158865676862026009729048525389272889703709380624434349438465164559591242984791355618727989751127260257309242805499481511142165616784856784942417419338154196561431152388897904866047119736434465720555151366859879507712533271194851766672024261634534292974370183919317337519761869292257947511511111895425764926171263133863980854536246390233199502174749146911367500644673909293464659053254182209374190247093969004854275674922622004129684228283369400286413197699863545912211106461047595912964876198783114172495242447965086668614473659343976994896679029656266765528726921384485164153780083326552118475505412074971594197272427677831237385443579950907872485700396062323506489811292749356021319775368577664875790645937426179486396681942844892307294288187671687510056569029216067321069225537944854772595983467728588640812585079820715315382504185719050646602130250650306723313760231069912835376365077115331890400516502810239814459239282321065702537572103441710647744406489548580900916084596895906189449738524638127337711843685456775272799845630310027842996833372802952394634016929280394482001/53084469288402965415857953902888840109250315594591772197851276288408082158869345776872184284291470495326835835491268017776297213098616208286592801322449982740570898437845767564651639451594841758957168240360072929342348878909784083488070009533176658698675760470010215436132534526706916446032842195249059760060209393388578176281027744679436285035293376786965957429093838689438026612141820062960073237944227430409290082873605748455349816343081466372681612738552636294666573661997989000563367893746123926316870120929629731301360766711677076606816082939449299471019533119911247114865751561110071173719092050562287666719013887097553109594042589835370732409680749273477741701995190365166750190649349508586781414000112900259875654673888811075100415790235930270448790550846107436360615795146817327563001398966815753145995110673462134196824939359497706430237425390060733252224220979131253874493851823165781457427314551881655553433521397260371393668335053627112038905459972042994824319713601980913921755210218082851146588240382210406887660412630451416112206306502796230074832738884324233514086958873577398927563897852887699678587467916741882087729456997268017154775450070371874680332524775280043635270781581135769020865808796073362505082201497885288236887117727248916243704472117062440908853938749830047482062530807255930310025959255017626077608884577821899189515192765061903944746945679900747890669013446056647522960607623949336195016784356934505954115977283306997415274187752372480232652878520163417566097389917356958213807994947634794209832173114356392822435844256992216702376456519427913660058510779720382422426729352627871147386069533497741201545766859622239986052843328404669795291152396764393702113455439610494964706121896827191760262984304690887475635610694078746800875955908479469409563047706020039725815572087005410536948676710051947334063697608908539017716795313119629533327813992071776512146390147185444968042597376280912548998385218672413833388480083312283356458666501168482077474943858309275329657545594008977132937574085616539588927255406484838471048801662983695044651588178399267847057683205128610922849562650411762874243138435345707386259866513245949164125352989897783775852403441398200260025840304184956928642989258546038224598392605412214974894309376
(Notice the slash at character 1570 into that digit sequence.)

Why does not R round function round big numbers

I need a R function that always returns same number of digits after the decimal point regardless of how big the argument is. I tried round() but it does not work this way. Here is my example:
Rweb:> round(111234.678912,4) # expect 111234.6789
[1] 111234.7
Rweb:> round(111234.678912/10,4) # expect 11123.4679
[1] 11123.47
Rweb:> round(111234.678912/100,4) # expect 1112.3468
[1] 1112.347
Rweb:> round(111234.678912/1000,4)
[1] 111.2347
Rweb:> round(111234.678912/10000,4)
[1] 11.1235
It does work if the argument is in exponential format but I need work with numbers in floating format.
It does round the number to the correct number of digits. However, R has limits on the number of digits it displays of very large numbers. That is- those digits are there, they just aren't shown.
You can see this like so:
> round(111234.678912,4)
[1] 111234.7
> round(111234.678912,4) - 111234
[1] 0.6789
You can use formatC to display it with any desired number of digits:
> n = round(111234.678912,4)
> formatC(n, format="f")
[1] "111234.6789"
> formatC(n, format="f", digits=2)
[1] "111234.68"
As #mnel helpfully points out, you can also set the number of digits shown (including those to the left of the decimal point) using options:
> options(digits=6)
> round(111234.678912,4)
[1] 111235
> options(digits=10)
> round(111234.678912,4)
[1] 111234.6789
For anyone else who, like me, thought the question was going to be about bignums :-), there's this to ponder :-)
Rgames> bfoo<-mpfr("1.234545678909887665453421")
Rgames> bfoo
1 'mpfr' number of precision 84 bits
[1] 1.234545678909887665453421
Rgames> round(bfoo,10)
1 'mpfr' number of precision 84 bits
[1] 1.23454567889999999999999999`
let x is a number with big decimal places.
x<-1111111234.6547389758965789345
Here x is a number with big decimal places , you can format decimal places
as your wish.
Such that we wish to take up to 8 decimal places of this number.
x<-c(1111111234.6547389758965789345)
y<-formatC(x,digits=8,format="f")
[1] "1111111234.65473890"
Here format="f" gives number in the usual decimal places say, xxx.xxx.
But if you wanted to get a integer number from this object x you use
format="d"
About "bignums", #Carl Witthoft:
Thanks, Carl. ... I did think about bignums, when I read it. Are you sure there
's a problem with the rounding?
See this:
> mpfr("1.2345456789", prec=84)
1 'mpfr' number of precision 84 bits
[1] 1.23454567889999999999999999
and note that Rmpfr (I'm the maintainer) does stay close to the underlying MPFR library. For round(), I've applied the logic/principle of f(x) returning a result with the same formal precision as x. If you want rounding with decreased formal precision, you can conveniently use roundMpfr():
> roundMpfr(bfoo, 32)
1 'mpfr' number of precision 32 bits
[1] 1.2345456788

Resources