How to apply mathematical operators on numbers more than 50 digits


#1

Say I have 10 numbers of 200+ digits how can I add or multiply or divide them.

Something as easy as

11111111111111....(200 digits)
+
22222222222222...(200 digits)

Is there a way we can add them precisely. Without converting them to float.


#2

I'd take a peek at this StackOverflow answer, which explores a few R wrappers to external libraries that handle extremely large integers. I doubt you'll find anything native to R (or, frankly, most other programming languages) that lets you do this sort of thing natively, to be honest; doing arithmetic on numbers on this scale with complete precision is extremely niche :confused:


#3

I checked that answer but I think there must be a better way. And I was able to calculate Fibonacci numbers up to 2000 digits in golang. So I thought if I could add such big numbers in R as well. Just for computational sake.


#4

Maybe! I can see that Go handles this sort of thing using math/big, rather than doing it out-of-the-box. If you're comfortable playing with other languages, you could try implementing an R package that allowed similar things using Rcpp. But as far as I'm aware, integers in R are 32-bit. I'm kind of surprised that 64-bit ones don't seem to be available (can anyone confirm this?), since they're common in other languages, but even 64-bit integers won't get you close to what you need here. Arbitrary precision arithmetic is a very specialist problem, so you might need to pop the hood and go a little lower level with this :slight_smile:


#5

This is probably the worst thing I have ever written.

@param ... Character vectors representing (large) integers
@return The numbers and the sum are printed to the console

BIGGADDD <- function(...) {
  library(magrittr)
  dots <- list(...)
  res <- 
    dots %>%
    lapply(formatC, width = max(vapply(dots, nchar, 0L)) + 10L) %>%
    lapply(strsplit, split = "") %>%
    lapply(unlist, recursive = FALSE) %>%
    lapply(function(x) {x[!nzchar(x) | x == " "] <- "0"; x}) %>%
    lapply(as.integer) %>%
    do.call(what = "rbind") %>%
    colSums
  
  for (i in rev(seq_along(res))) {
    if (res[i] >= 10L) {
      res[i - 1L] <- res[i - 1L] + {res[i] %/% 10L}
      res[i] <- res[i] %% 10L
    }
  }
  
  
  
  cat(paste0(dots, collapse = "\n"), sep = "")
  cat("\n")
  cat(sub("^0+", "", paste0(res, collapse = "")), sep = "")
}

x <- paste0(rep("1", 100), collapse = "")
y <- paste0(rep("2", 100), collapse = "")
BIGGADDD(x, y)
#> 1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
#> 2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222
#> 3333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333

Created on 2018-09-27 by the reprex package (v0.2.1)


#6

I can confirm, that R doesn't support 64-bit integers natively. There is always bit64 package if you need it, but there is a talk on R-devel about finally introducing it to base R.


#7

Very good attempt sir. Hats off.

But we were looking for something more generic. I don't have any use case for this but it could be if you are interested in calculating prime numbers which don't follow riemann hypothesis or calculating large fibonacci numbers or something similar. which just need computation it could have been useful.

Just wanted to confirm if there is something similar in R.

But thanks for replying and great effort.


#8

What-have-we-done-to-Lauren-515x300

:laughing:


#9

This removes cap over big number by using string. But we will then need to reimplement multiplication functions , power functions, log functions and so much more.

I Just meant the concept is great.

:rofl::rofl::rofl::rofl:


#10

Edit: The VeryLargeIntegers package isn't good for anything going outside integers (e.g., division). If you need that functionality, contact the package maintainer.

I haven't used it, so I can't vouch for it, but there is the VeryLargeIntegers package. Other similar packages are listed in the NumericalMathematics task view.


#12

Thanks works like magic it worked just fine.

:hugs::hugs::hugs::hugs::hugs::hugs:


#13

Somehow I think this isn't the solution to this problem. Please look at the reprex and you will understand what I mean.



# Load_library ------------------------------------------------------------

library(VeryLargeIntegers)


# create number -----------------------------------------------------------
number<-paste(rep(x = 1,10),sep = '',collapse = '')
x<-as.vli(number)

# Some manupulation that work ---------------------------------------------
x
#> Very Large Integer: 
#> [1] 1111111111

x^2
#> Very Large Integer: 
#> [1] 1234567900987654321

x+2*x
#> Very Large Integer: 
#> [1] 3333333333


# Problem with division or double rep -------------------------------------

x/10^7
#> Very Large Integer: 
#> [1] 111111

####
## Shoul be 111.1111111
####


# lets take another number ------------------------------------------------
number2<-paste(rep(x = 2,10),sep = '',collapse = '')
y<-as.vli(number2)


y/x ## is right
#> Very Large Integer: 
#> [1] 2

x/y  ## is wrongs
#> Very Large Integer: 
#> [1] 0

Created on 2018-09-28 by the reprex package (v0.2.1)


#14

You're right, the package isn't useful for division when the result isn't an integer. It also has problems with logarithms, so approaching it that way isn't possible.

After playing around with it, I'm not a fan of what it is now. It could definitely be improved. If you would benefit, consider emailing the maintainer to ask for non-integer division.


#15

I am just trying to find out if there is such thing possible in R nothing else. I have no benefit for this but I think he had mentioned it exclusively. So he does know the limitation of the package.


#16

You could try the other packages listed in the task view. For instance, the gmp package seems fine:

library(gmp)

number <- paste(rep(1, 10), collapse = '')
x <- as.bigz(number)
number2 <- paste(rep(2, 10), collapse = '')
y <- as.bigz(number2)
y / x
# Big Rational ('bigq') :
# [1] 2
x / y
# Big Rational ('bigq') :
# [1] 1/2

And it even supports vectors of large numbers:

as.bigz(c(number, number2))
# Big Integer ('bigz') object of length 2:
# [1] 1111111111 2222222222

#17

it worked perfectly fine if you have enough RAM you can keep on going. On my 8gb Laptop I was able to accomplish multiplying 2 numbers who has a size of a million digits each.

Great solution People should know about these things too.


#18

Well, raising awareness and helping people to navigate available packages in specific subject areas is the whole point of the Task Views: https://cran.r-project.org/web/views