-1

I learnt about Karatsuba algorithm which allows me to multiply very big numbers using divide and conquer method.

Here's my code. I wrote a function which returns the length of a number then I write the multiply function and I used the method with 4 recursive calls.

#include <iostream>
#include <algorithm>
#include <math.h>

using namespace std;

int numberLength(long long value) {
    int counter = 0;
    while (value != 0)
    {
        counter++;
        value /= 10;
    }
    return counter;
}

long long multiply(long x, long y) {
    int xLength = numberLength(x);
    int yLength = numberLength(y);

    int n = max(xLength, yLength);

    if (n < 10) {
        return x*y;
    }

    long multiplier = pow(10, n/2);
    long xS = x/multiplier;
    long xD = x - (xS * multiplier);
    long yS = y/multiplier;
    long yD = y - (yS * multiplier);

    return multiply(xS,yS*pow(10,n)) + multiply(xS,yD*pow(10,n/2)) + multiply(xD,yS*pow(10,n/2)) + multiply(xD,yD);

}

The problem is that if I call the function multiply() with some numbers length bigger than 10 then I get the error Segmentation fault. Where's the problem?

varo111
  • 307
  • 1
  • 3
  • 8
  • Looks like it isn't crashing here: https://godbolt.org/z/YT3qr61T7. Any particular compiler options/test setups you're using? – mattlangford Apr 19 '21 at 21:59
  • `pow(10, n/2)` is float meaning you got only `2^53` or `2^24` top limit of the resulting value if you want precise integer .... also using bigint pow for bigint multiplication is simply a bad idea .... – Spektre Apr 20 '21 at 07:43

1 Answers1

1

You are going to breach the stack limit and that would lead to a stack overflow in the recursive multiply() function for numbers with lengths >= 10. I tried this driver function

multiply(123456789, 1234567891);

and compiled this with -fsanitize=address. This was the output:

==1==ERROR: AddressSanitizer: stack-overflow on address 0x7fffe22e9fb8 (pc 0x0000004fb85d bp 0x7fffe22ea050 sp 0x7fffe22e9f00 T0)

Also, try compiling your program with -fsanitize=undefined to take a look at other errors in the logic, one being

if (n < 10) {
    return x*y;
}

Passing in multiply(123456789, 1234567891) will cause an overflow since that value can't be accommodated in a long (usually of 32-bits). Change that to:

if (n < 10) {
    return (long long)x*y;
}
Zoso
  • 3,273
  • 1
  • 16
  • 27