Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dealing with large numbers in R [Inf] and Python

Tags:

python

r

I am learning Python these days, and this is probably my first post on Python. I am relatively new to R as well, and have been using R for about a year. I am comparing both the languages while learning Python. I apologize if this question is too basic.

I am unsure why R outputs Inf for something python doesn't. Let's take 2^1500 as an example.

In R:

nchar(2^1500)
[1] 3
2^1500
[1] Inf

In Python:

len(str(2**1500))
Out[7]: 452
2**1500
Out[8]: 3507466211043403874...

I have two questions:

a) Why is it that R provides Inf when Python doesn't.

b) I researched How to work with large numbers in R? thread. It seems that Brobdingnag could help us out with dealing with large numbers. However, even in such case, I am unable to compute nchar. How do I compute above expression i.e. 2^1500 in R

2^Brobdingnag::as.brob(500)
[1] +exp(346.57)
> nchar(2^Brobdingnag::as.brob(500))
Error in nchar(2^Brobdingnag::as.brob(500)) : 
  no method for coercing this S4 class to a vector
like image 447
watchtower Avatar asked Dec 24 '17 21:12

watchtower


People also ask

How do you handle large numbers in Python?

Python supports a "bignum" integer type which can work with arbitrarily large numbers. In Python 2.5+, this type is called long and is separate from the int type, but the interpreter will automatically use whichever is more appropriate.

How does Python store long integers?

Python, however, doesn't use a fixed number of bit to store integers. Instead, Python uses a variable number of bits to store integers. For example, 8 bits, 16 bits, 32 bits, 64 bits, 128 bits, and so on. The maximum integer number that Python can represent depends on the memory available.

How many digits can python handle?

The pythonic way Similarly for python, "digit" is in base 2³⁰ which means it will range from 0 to 2³⁰ - 1 = 1073741823 of the decimal system.

How do you create a big int in Python?

Type int(x) to convert x to a plain integer. Type long(x) to convert x to a long integer.


2 Answers

In answer to your questions:

a) They use different representations for numbers. Most numbers in R are represented as double precision floating point values. These are all 64 bits long, and give about 15 digit precision throughout the range, which goes from -double.xmax to double.xmax, then switches to signed infinite values. R also uses 32 bit integer values sometimes. These cover the range of roughly +/- 2 billion. R chooses these types because it is geared towards statistical and numerical methods, and those rarely need more precision than double precision gives. (They often need a bigger range, but usually taking logs solves that problem.)

Python is more of a general purpose platform, and it has types discussed in MichaelChirico's comment.

b) Besides Brobdingnag, the gmp package can handle arbitrarily large integers. For example,

> as.bigz(2)^1500
Big Integer ('bigz') :
[1] 35074662110434038747627587960280857993524015880330828824075798024790963850563322203657080886584969261653150406795437517399294548941469959754171038918004700847889956485329097264486802711583462946536682184340138629451355458264946342525383619389314960644665052551751442335509249173361130355796109709885580674313954210217657847432626760733004753275317192133674703563372783297041993227052663333668509952000175053355529058880434182538386715523683713208549376
> nchar(as.character(as.bigz(2)^1500))
[1] 452

I imagine the as.character() call would also be needed with Brobdingnag.

like image 188
user2554330 Avatar answered Oct 21 '22 00:10

user2554330


Apparently python uses arbitrary precision integers by default when needed. R does not. However, there are many useful R packages to perform arbitrary precision arithmetic. Which package to pick depends on the use case.

To bring up a package that hasn't been discussed yet, consider the Rmpfr package:

> library(Rmpfr)
> a <- 2^mpfr(1500, 10000)
> a
1 'mpfr' number of precision  10000   bits 
[1] 35074662110434038747627587960280857993524015880330828824075798024790963850563322203657080886584969261653150406795437517399294548941469959754171038918004700847889956485329097264486802711583462946536682184340138629451355458264946342525383619389314960644665052551751442335509249173361130355796109709885580674313954210217657847432626760733004753275317192133674703563372783297041993227052663333668509952000175053355529058880434182538386715523683713208549376

It requires you to set a precision, but if you make it large enough it can hold 2^1500 as integer.

However, it also doesn't seem to define an as.character() function:

> as.character(a)
[1] "<S4 object of class \"mpfr1\">"

So if your problem is specifically to count digits, then the gmp package as discussed in this answer is probably the way to go. On the other hand, if you're interested in arbitrary precision floating point arithmetic, Rmpfr might be a better choice.

like image 35
Claus Wilke Avatar answered Oct 20 '22 22:10

Claus Wilke