2

I have the following problem:

> 1e20 %% 3
[1] 0
Warning message:
probable complete loss of accuracy in modulus 

The result can't be correct and I'm sure it is because 1e20 is really big. But I want to solve calculations like this in R. Is there a chance to come up with this?

EDIT: I want to do the following challenge: https://www.codeabbey.com/index/task_view/modular-calculator

This is my code:

library(tidyverse)
library(magrittr)

get_result <- function(.string){

  terms <- .string %>% 
    str_split("\n") %>%
    unlist %>% 
    str_replace("%", "%%") %>% 
    str_squish

  terms[1] %<>% 
    str_c("x <<- ", .)

  terms[2:length(terms)] %<>%
    str_c("x <<- x ", .)

    map(terms, ~ {
      eval(parse(text = .x))      
      })

    x

}

get_result("6
+ 12
           * 99
           + 5224
           * 53
           * 2608
           * 4920
           + 48
           + 7
           * 54
           * 4074
           + 76
           * 2
           * 97
           + 4440
           + 3
           * 130
           + 432
           * 50
           * 1
           + 933
           + 3888
           + 600
           + 9634
           * 10
           * 59
           + 62
           * 358
           + 82
           + 1685
           * 78
           + 8
           * 266
           * 256
           * 26
           * 793
           + 1248
           * 746
           * 135
           * 10
           * 184
           + 4
           * 502
           * 60
           + 9047
           * 5
           + 416
           * 7
           * 6287
           * 8
           % 4185")

With the real test data I get a huge number before I want to use the modulus

TobiSonne
  • 1,044
  • 7
  • 22
  • You want to do integer arithmetic on a large (> 64-bit) integer? The warning about 'modulus' is only referring to the `%%`/modulo operator, not to all arithmetic. log_2(1e20) = 66.43 bits, so by definition if you try to store it as a 64b integer it will lose the low bits. – smci Dec 31 '19 at 19:12
  • I want to do modulus with very large numbers. – TobiSonne Dec 31 '19 at 19:14
  • I want to do this challenge in R with the test data: https://www.codeabbey.com/index/task_view/modular-calculator – TobiSonne Dec 31 '19 at 19:14
  • 1
    Please show us the exact input expression you used, and your code. You wouldn't just input `1e20` into a modular calculator. You will want to implement `%%` and `*` for exactness with large integers. – smci Dec 31 '19 at 19:26
  • Your expression `((5+3)*7+10)*2*3 +1` is only 397 ! It's not even a 9-bit number, let alone a 67-bit number. You must have gotten order precedence wrong somewhere. You don't actually need big integers or arbitrary-precision. – smci Dec 31 '19 at 19:33
  • That was only the example. The real challenge was too big for the question because it was too much code. – TobiSonne Dec 31 '19 at 19:35
  • 1
    I doubt the challenge is asking you to implement an arbitrary-precision arithmetic library since its rules say *"All numbers will not exceed 10000 (though intermediate results could be very large)"*. Maybe you can get by with 128b and maybe just with 64b. In order to fix your code, we need to actually see both your code and the input data you used. SO rules require you post a Minimal Complete Verifiable Example [MCVE](https://stackoverflow.com/help/minimal-reproducible-example). Not just a spec. – smci Dec 31 '19 at 19:38
  • There were really large numbers at the end. The last intermediate number was `300395359823277532724413963604303819835990034367536223331672`. I made the challenge with `gmp`. – TobiSonne Dec 31 '19 at 19:42

3 Answers3

5

Your numbers are too large for R's numeric data type. See this answer which explains how to see the minumum and maximum values that can be represented in the numeric type. It is approximately 53 bits, which your number 1e20 exceeds.

Also see CRAN's FAQ (section 7.31) which explains a little more about floating-point representation in R.

As for how to handle large numbers in R, have a look at this blog post that describes the "gmp" package that may be helpful to you.

KamRa
  • 349
  • 2
  • 12
3

To implement exact integer arithmetic on quantities larger than 64b, either:

  1. use an arbitrary-precision package e.g. gmp or similar see "Multiplication of large integers in R" or...
  2. more in the spirit of your 'Modular Calculator' challenge, implement arithmetic operations with a thought to exactness for big integers. (Please show us the exact input expression you used, and your code)

You want to do integer arithmetic on a large (> 64-bit) integer? The warning about 'modulus' is only referring to the %%/modulo operator, not to all arithmetic. log_2(1e20) = 66.43 bits, so by definition if you try to store it as a 64b integer it will lose the low bits.

UPDATE: Please give us an actual MCVE example with the input you used to get 1e20 as an intermediate result. The expression they give ((5+3)*7+10)*2*3 +1 is only 397.

smci
  • 32,567
  • 20
  • 113
  • 146
1

I only had to change:

terms[2:length(terms)] %<>%
    str_c("x <<- x ", .)

into:

terms[2:length(terms)] %<>%
    str_c("x <<- gmp::as.bigz(x) ", .)
TobiSonne
  • 1,044
  • 7
  • 22