-2

I've two huge natural numbers saved as strings: a and b. Each of the numbers can have up to 150 characters. I need to get result of ab in a reasonable time.

I searched for optimal solution, but always a is a big string and b - int.

I tried simply solution:

string power(string n1, string n2) {
    string result = n1;

    if(n2 == "0")
        return "1";

    do {
        result = multiply(result, n1);
        n2 = decrement(n2);
    }
    while(n2 != "1");

    return result;
}

How can I get result in less time?

user4581301
  • 33,082
  • 7
  • 33
  • 54
  • 1
    What do you need this for? What's the next thing you're planning to do once you have that power? I suspect that you may not actually need to compute the entire power at all. – Mark Dickinson Jan 31 '19 at 20:43
  • 1
    Define "reasonable". Also explain why you can't use an existing "bignum" library. – tadman Jan 31 '19 at 20:46
  • After that's power i need to get modulo from the result and third big numer. I have method to get this modulo, but i need get power faster. – LukasKhuka Jan 31 '19 at 20:52
  • 6
    Then you don't have to calculate the power. Modular exponentiation is the name of the trick. – Evg Jan 31 '19 at 20:53
  • @Evg b is string. – LukasKhuka Jan 31 '19 at 20:55
  • 1
    @LukasKhuka to decrement one by one 10^150 you will need like a billion billion years, I confirm you need faster way ^^ – bruno Jan 31 '19 at 20:56
  • 1
    Please provide a [mcve]. Currently we dont know how you get a result to begin with. How much is less time? – 463035818_is_not_an_ai Jan 31 '19 at 21:16
  • [Handling this for large powers of 2](/questions/24503611/modular-exponentiation-over-a-power-of-2) isn't quite a duplicate, but should go a long way toward getting you a solution. – Prune Jan 31 '19 at 22:08
  • The magic google phrase is "exponentiation by squaring". Do the modulus after *every* multiply. – Matt Timmermans Feb 01 '19 at 02:21

1 Answers1

0

You need to calculate much less when you reuse results.

For Example: 5^8 = 5^4*5^4 = 5^2*5^2*5^2*5^2 = 5*5*5*5*5*5*5*5

You don't need to do all 7 multiplications, only 5*5, 5^2*5^2, 5^4*5^4 (3 multiplications)

The following code is Python code (because i wanted to easily test it), but I hope you see the point.

def powBase10(a,n):
    if(n==0):
        return 1
    x=powBase10(a, int(n/10))
    if(n%10==0):
        return (x*x*x*x*x*x*x*x*x*x)
    if(n%10==1):
        return (a*x*x*x*x*x*x*x*x*x*x)
    if(n%10==2):
        return (a*a*x*x*x*x*x*x*x*x*x*x)
    if(n%10==3):
        return (a*a*a*x*x*x*x*x*x*x*x*x*x)
    if(n%10==4):
        return (a*a*a*a*x*x*x*x*x*x*x*x*x*x)
    if(n%10==5):
        return (a*a*a*a*a*x*x*x*x*x*x*x*x*x*x)
    if(n%10==6):
        return (a*a*a*a*a*a*x*x*x*x*x*x*x*x*x*x)
    if(n%10==7):
        return (a*a*a*a*a*a*a*x*x*x*x*x*x*x*x*x*x)
    if(n%10==8):
        return (a*a*a*a*a*a*a*a*x*x*x*x*x*x*x*x*x*x)
    if(n%10==9):
        return (a*a*a*a*a*a*a*a*a*x*x*x*x*x*x*x*x*x*x)

def powBase2(a,n):
    if(n==0):
        return 1
    x=powBase2(a, int(n/2))
    if(n%2==0):
        return (x*x)
    if(n%2==1):
        return (a*x*x)

The code should be faster when you use base 2 instead of base 10. The reason why should adjust the algorithm to your base is, that the division by the base can be done by deleting the last digit, so there is no real calculation needed for division.

The number of multiplications you need should be logarithmic with this approach instead of linear so it should be no problem with a few hundred digits.

You could optimize the base-10 code again with the same approach

for example instead of:
x*x*x*x*x*x 
use:
y=x*x
y=y*y*y

But this will only result in a constant speedup.

jjj
  • 575
  • 1
  • 3
  • 16