Square root of a number to 100 decimal places - r

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

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

Why does R display wrong number with large numbers?

When I save a large number in R as an object the wrong number is saved? Why is that?
options("scipen"=100, "digits"=4)
num <- 201912030032451613
num
#> [1] 201912030032451616
Created on 2019-12-12 by the reprex package (v0.2.1.9000)
As #Roland says, this is a floating point issue (the Wikipedia page on floating point numbers is as good as anything). Unpacking it a bit though, R has specific integer format but it is limited to 32 bit integers:
> str(-2147483647L)
int -2147483647
> str(2147483647L)
int 2147483647
> str(21474836470L)
num 21474836470
Warning message:
non-integer value 21474836470L qualified with L; using numeric value
So, when R gets your number it is storing it as a floating point number not an integer. Floating point numbers are limited in how much precision they can store and typically only have about 17 significant digits. Because your number has more significant digits than that there is loss of precision. Losing precision in the smallest digits doesn't usually matter for computer arithmetic, but if your big number is a key of some kind (or a date stamp) then you are in more trouble. The bit64 package is designed with this kind of use case in mind, or you could import it as a string, depending on what you want to do.

R largest/smallest representable numbers

I'm trying to get the largest/smallest representable number in R.
After typing ".Machine"
I got:
$double.xmin
[1] 2.225074e-308
$double.xmax
[1] 1.797693e+308
However even if I type 2.225074e-309 in R command prompt I get 2.225074e-309 instead of the expected 0
How can I find the largest/smallest number for which adding or subtracting 1 would lead to either Inf(Adding 1 to largest number) or 0(subtracting 1 from smallest number) ?
.Machine$double.xmin gives the value of the smallest positive number whose representation meets the requirements of IEEE 754 technical standard for floating point computation. As is mentioned in the Wikipedia article on double-precision floating point numbers, that standard requires that:
If a decimal string with at most 15 significant digits is converted to IEEE 754 double precision representation and then converted back to a string with the same number of significant digits, then the final string should match the original. If an IEEE 754 double precision is converted to a decimal string with at least 17 significant digits and then converted back to double, then the final number must match the original.
The same article goes on to note that, by compromising precision, even smaller positive numbers (which do not meet the standards' precision requirements) can be represented:
The 11 bit width of the exponent allows the representation of numbers between 10-308 and 10308, with full 15–17 decimal digits precision. By compromising precision, the subnormal representation allows even smaller values up to about 5 × 10-324.
R's doubles behave in exactly this way, as is noted in the Details section of ?.Machine:
Note that on most platforms smaller positive values than
‘.Machine$double.xmin’ can occur. On a typical R platform the
smallest positive double is about ‘5e-324’.
To confirm that that is the smallest positive value that can be represented using R's doubles and to see the cost in loss of precision, try out a few operations like this:
5e-324
# [1] 4.940656e-324
2e-324
# [1] 0
1.4 * 5e-324
# [1] 4.940656e-324
1.6 * 5e-324
# [1] 9.881313e-324
Here are some representations using SAS, IEEE 754 Big Endian?
data _null_;
y=constant('big');
put y hex16.;
put y E21.3;
run;quit;
Biggest
7FEFFFFFFFFFFFFF
1.79769313486230E+308
data _null_;
y=constant('small');
put y hex16.;
put y E21.3;
run;quit;
Smallest
0010000000000000
2.22507385850720E-308
I am not sure the smallest because SAS may set aside some values for missings.

How to work with large numbers in R?

I would like to change the precision in a calculation of R. For example I would like to calculate x^6 with x = c(-2.5e+59, -5.6e+60). In order to calculate it I should change the precision in R, otherwise the result is Inf, and I don't know how to do it.
As Livius points out in his comment, this is an issue with R (and in fact, most programming language), with how numbers are represented in binary.
To work with extremely large/small floating point numbers, you can use the Rmpfr library:
install.packages("Rmpfr")
library("Rmpfr")
x <- c(-2.5e+59, -5.6e+60)
y <- mpfr(x, 6) # the second number is how many precision **bits** you want - NB: not decimal places!
y^6
# 2 'mpfr' numbers of precision 6 bits
# [1] 2.50e356 3.14e364
To work with numbers that are even larger than R can handle (e.g. exp(1800)) you can use the "Brobdingnag" package:
install.packages("Brobdingnag")
library("Brobdingnag")
## An example of a single number too large for R:
10^1000.7
# [1] Inf
## Now using the Brobdingnag package:
10^as.brob(1000.7)
# [1] +exp(2304.2)

Is there a way to store a large number precisely in R?

Is there a way to store a large number precicely in R?
double is stored as a binary fraction and its precision varies with the value, and integer has limited range of 4 bytes.
What if I wanted to store a very large number precisely?
You can try the bigz class from the gmppackage:
> library("gmp")
> 2^10000
[1] Inf
> 2^(as.bigz(10000))
[1] "199506.... and a LOT of more numbers!
It basically stores the number as a string and so avoiding the integer/double limits.
It depends on what you mean by large number:
If you want numbers above the top end of double precision arithmetic, there is the Brobdingnag package
If you want more precision there are the gmp and related Rmpfr packages.

Resources