8

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
watchtower
  • 4,140
  • 14
  • 50
  • 92
  • look at `.Machine$double.xmax` (and other limits contained in `Machine`) – MichaelChirico Dec 24 '17 at 21:12
  • 2
    if you really just want to know the number of digits, it's `1500*log10(2)`-ish – MichaelChirico Dec 24 '17 at 21:13
  • @Michael - Thanks for your help. I ran `.Machine$double.xmax` and got `1.797693e+308`. Also, `2^1500` is just an example. I am more concerned about getting the same answer in R, like Python, rather than `Inf`. I'd appreciate your help. Also, I am unsure whether machine limitations will exist because Python is able to provide me with an answer, while R isn't giving me the answer. I am very surprised. – watchtower Dec 24 '17 at 21:16
  • see also: https://stackoverflow.com/questions/538551/handling-very-large-numbers-in-python – MichaelChirico Dec 24 '17 at 21:59
  • 1
    Possible duplicate of [Large powers in R](https://stackoverflow.com/questions/22318985/large-powers-in-r) – greybeard Jan 08 '18 at 07:38

2 Answers2

7

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.

user2554330
  • 37,248
  • 4
  • 43
  • 90
  • 1
    good so far. Might be worth (1) incorporating details from @MichaelChirico's comment in your answer (comments are ephemeral); (2) commenting that Python only handles arbitrarily large *integers*, e.g. `2.01**1500` gives an `OverflowError` in Python (whereas `2.01^1500` gives `Inf` in R ...) unless you use something like [mpmath](http://mpmath.org/) ... – Ben Bolker Dec 24 '17 at 22:31
  • The Brobdingnag package doesn't define `as.character()`. – Claus Wilke Dec 24 '17 at 22:41
6

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.

Claus Wilke
  • 16,992
  • 7
  • 53
  • 104