0

This comes up when evaluating a rolling hash of a string by subtracting the old weight of a character and adding a new weight for a new character.

Python has infinite length digits and is able to store such large numbers:

num = -56061846576641933068511861128435847024473459936647893758520084401988341
div = 10**9 + 7
mod = num % div #504892002

But in Swift, as I keep doing calculations, I lose precision and get bigger and bigger errors. For example, at some point in my calculations, the above number had this value:

var num = Double("-5.606184657664193e+70")
var div = pow(Double(10), 9) + 7
var mod = num!.truncatingRemainder(dividingBy: div)
mod = mod < 0 ? mod + div : mod //215272131.0

I looked into Decimal, but it does not support the mod operation. And Int64 will also be too small for such numbers. Are there any other native options, without adding convenience extensions?

Also, How do you get the int and modulo (mod) of division with an NSDecimalNumber does not help. It suggests extensions or has examples that do not deal with big numbers.

28
  • 2
    How could -5.606184657664193e+70 possibly be exactly equal to -56061846576641933068511861128435847024473459936647893758520084401988341? Commented Nov 14, 2023 at 0:45
  • 1
    I agree that your question is much better now. Can you show an example of how you got the number you have? I suspect that you can do the modulo operations as you go and never exceed 1e9+7 Commented Nov 14, 2023 at 2:00
  • 1
    Check this out: en.wikipedia.org/wiki/Modular_exponentiation. The idea is to implement pow(base, len - 1) mod div in a way that does not overflow to begin with. Integer math is better than float when you can use it. Commented Nov 14, 2023 at 4:03
  • 1
    President James, I missed that. Thanks. The OP needs to edit the question. It is an XY problem. He doesn't need a big integer API for that purpose only. Commented Nov 15, 2023 at 14:14
  • 1
    See Memory-efficient method. Let m = 10000000007. Think about these: r_1 = (m-26) % m, r_2 = (r_1 * 26) % m, r_3 = (r_2 * 26) % m, ... r_49 = (r_48 * 26) % m. The r_i *26 will not overflow because r_i < m, r_i * 26 < m * 26 < 2^63-1. Commented Nov 16, 2023 at 1:10

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.