1

I am trying to implement kartsuba's algorithm in c, I followed the pseudo code on Wikipedia, but the problem is I don't always get the correct result.

here is the implementation:

long long karatsuba(char* a,char* b){
if (atoi(a)<10 || atoi(b)<10)
    return atoi(a)*atoi(b);
int m = ((strlen(a)<strlen(b))?strlen(a):strlen(b))/2;

char* high1 = slice(a,0,m);
char* low1 = slice(a,m,strlen(a)-m);
char* high2 = slice(b,0,m);
char* low2 = slice(b,m,strlen(b)-m);


long long z0 = karatsuba(low1,low2);
long long z1 = karatsuba(add(low1,high1),add(low2,high2));
long long z2 = karatsuba(high1,high2);

free(low1);
free(high1);
free(low2);
free(high2);    

return (z2*pow(10,m*2))+((z1-z2-z0)*pow(10,m)) + z0;
}

this is the slice function, it is used to partition a number into 2:

char* slice(char* s,int a,int n){
    char* r = calloc(n+1,sizeof(char));
    strncpy(r,s+a,n);
    return r;
}

And this is the add function which is used to add 2 numbers:

char* add(char* a,char* b){
char* r = calloc((strlen(a)>strlen(b)?strlen(a):strlen(b))+2,sizeof(char));
sprintf(r,"%lld",atoi(a)+atoi(b));
return r;
}

P.S: Just out of curiosity, I saw in many implementations the use of max (size(num1),size(num2)) instead of min, is that ok and does it change anything?

LonelyDaoist
  • 665
  • 8
  • 22
  • 1
    "I don't always get the correct result" - what data do you feed in, what results do you expect and which ones are you actually getting? – ForceBru Mar 24 '19 at 15:18
  • the algorithm is used to multiply two numbers a and b in string format. e.g for a="1234" and b="5678" I get 6592652 while the result should be 7006652 – LonelyDaoist Mar 24 '19 at 15:19
  • 3
    You *tried* to follow the en.wikipedia pseudocode. For the "scaling" by `10 ^ m2` to be correct, which part returned by, say `split_at(num1, m2)` *has to* have length *m2*: the more or the less significant part? Re-read the paragraph [Basic step](https://en.m.wikipedia.org/wiki/Karatsuba_algorithm#Basic_step). – greybeard Mar 24 '19 at 15:47
  • It should be the least significant part, right? thank you for the answer I'll try and fix it – LonelyDaoist Mar 24 '19 at 16:01

1 Answers1

0

thanks to @greybeard's comment, apparently the problem was that I partitioned the numbers in a way that the most significant part has m digits, instead it should be the least significant part, so to fix it:

I changed this part:

char* high1 = slice(a,0,m);
char* low1 = slice(a,m,strlen(a)-m);
char* high2 = slice(b,0,m);
char* low2 = slice(b,m,strlen(b)-m);

to:

char* high1 = slice(a,0,strlen(a)-m);
char* low1 = slice(a,strlen(a)-m,m);
char* high2 = slice(b,0,strlen(b)-m);
char* low2 = slice(b,strlen(b)-m,m);
LonelyDaoist
  • 665
  • 8
  • 22