Click here to Skip to main content
15,887,083 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
Dear Expert

I am trying to solve karastooba multiplication using basic C commands. I have created a function to add two numbers which are stored as string.
void sum(a,b,c) will assign a+b to c.
I was able to get sum for any input when I used this function alone. But when I used this in recursive function i am getting some wrong results. I called this function in consecutive steps, but I am getting result only for one function call. What surprising me is that I got perfect result sometimes when I changed the name of variables. Will name of variable have any influence in program ?
I am doing all these with Code::Block

What I have tried:

C
#include<stdio.h>
#include<string.h>
void sum(char*,char*,char*);
void prod(char*,char*,char*);
void seperate(char *a,char *b, char *c, char *d, char *x, char *y);
void powercalculation(char*,char);
void difference(char*, char*,char*);
unsigned char pub=0;
int main()
{

   char x[50],y[50],z[50];
    gets(x);
    gets(y);
    prod(x,y,z);
    puts(z);
    return(0);
}

void prod(char *x, char *y, char *z)
{
      char a[25],b[25],c[25],d[25],n;
      char temp1[50],temp2[50],temp3[50],temp4[50],ac[50],bd[50];

    if(strlen(x)>strlen(y))
        n=strlen(x);
    else
        n=strlen(y);
    if(strlen(x)==1||strlen(y)==1)           //either of input is singlr digit
    {

        strcpy(temp1,"0");
        strcpy(temp2,"0");
        if(strlen(x)==1)                    //adding y , x[0] times
        {
            temp3[0]=x[0];
            for(;temp3[0]>'0';temp3[0]--)
            {
                sum(temp1,y,temp2);
                strcpy(temp1,temp2);
            }
        }
        else                                //adding  , y[0] times
         {
            temp3[0]=y[0];
             for(;temp3[0]>'0';temp3[0]--)
            {
                sum(temp1,x,temp2);
                strcpy(temp1,temp2);
            }
        }
        strcpy(z,temp2);                    //copy result and return
        return;
    }
    else
    {
        seperate(a,b,c,d,x,y);              //deriving a,b,c,d from x and y
        sum(a,b,temp1);                     //a+b
        sum(c,d,temp2);                     //c+d
        puts(temp1);
        puts(temp2);
        prod(temp1,temp2,temp3);            //(a+b)*(c+d)
        prod(a,c,ac);                       //a*c
        prod(b,d,bd);                       //b*d
        difference(temp3,ac,temp1);         //(a+b)*(c+d)-ac
        difference(temp1,bd,temp3);         //(a+b)*(c+d)-ac-bd
        powercalculation(temp2,(2*n));      //powercalculation return 10^(n/2), for n even, it returns n/2 zeros,
                                            //Here argument is 2*n so returns n zeros
        strcat(ac,temp2);                   //(10^n)*a*c
        sum(ac,bd,temp2);                   //(10^n)ac+bd
        powercalculation(temp3,(n));
        if(n%2==0)                          //if n is even temp3 is n/2 number of zeros
        strcat(temp1,temp3);
        else
        prod(temp1,temp3,temp4);            //(10^n/2){(a+b)(c+d)-ac-bd}
        sum(temp4,temp2,z);
        return;
    }
}




//function for difference of a and b to c. a should be higher than b
//if difference of two fifty digit number is two digit, difference string size will be 2, no duplicate zeros in MSB


void difference(char *a, char *b, char *c)         //a should be higher
{
    char temp[10],temp1,temp2,i,k;
    temp1=strlen(a)-1;
    temp2=strlen(b)-1;

    for(i=0;temp2>=0;temp2--,temp1--,i++)           //taking individual digit and subtracting, diffenrce is stored in reverse form, ie LSB in temp[0]
    {
        if(a[temp1]>=b[temp2])
            temp[i]=a[temp1]-b[temp2]+48;
        else                                        //in case of borrow
        {
            temp[i]=a[temp1]+10-b[temp2]+48;
            if(a[temp1-1]>48)
                a[temp1-1]--;
            else
            {

                for(k=temp1-2;a[k]=='0';k--);
                a[k]--;

                for(k+=1;k<=temp1-1;k++)
                    a[k]='9';

            }
        }

    }
    for(;temp1>=0;temp1--,i++)                      //if size of b is less
    temp[i]=a[temp1];

    for(i-=1;temp[i]=='0';i--);                     //removing zeros in MSB
    for(k=0;i>=0;k++,i--)                           //reversing string
        c[k]=temp[i];
    if(k>0)
    c[k]='\0';
    else
        strcpy(c,"0");
    return;
}



//function to calculate power(10,n/2)

void powercalculation(char *a, char n)              //to calculate 10^(n/2)
{

    if(n%2==0)                                      //it will return n/2 zeros
    {
            strcpy(a,"00000000000000000000000000000000000000000000000");
            n/=2;
            a[n+1]='\0';
    }
    else                                            //return 10^(n/2)
    {
            strcpy(a,"31622776601683793319988935444327");//sqrt(10)=3.1622776601683793319988935444327
            n/=2;
            a[n+1]='\0';
    }
    return;

}



//function to seperate x,y into a,b,c,d

void seperate(char *a,char *b, char *c, char *d, char *x, char *y)
{
    char n,l1,l2,i,j,k,m,flag;
    l1=strlen(x);
    l2=strlen(y);
    if(l1>l2)
        n=l1;
    else
        n=l2;


if(l1==l2)                                      //size of both numbers same
if(n%2==0)                                      //if size is even
    {
    a[n/2]=b[n/2]=c[n/2]=d[n/2]='\0';
    for(i=n-1,j=(n/2)-1;i>=(n/2);i--,j--)       //assigning x and y to a,b,c,d
    {
        a[j]=x[i-(n/2)];
        b[j]=x[i];
        c[j]=y[i-(n/2)];
        d[j]=y[i];
    }
    }
    else                                        //if numbers are odd
    {
        a[n/2]=c[n/2]='\0';
        b[(n/2)+1]=d[(n/2)+1]='\0';
        b[n/2]=x[n-1];
        d[n/2]=y[n-1];
        for(i=n-2,j=(n/2)-1;j>=0;i--,j--)
        {
        a[j]=x[i-(n/2)];
        b[j]=x[i];
        c[j]=y[i-(n/2)];
        d[j]=y[i];
        }
    }


   else if(l1>l2)                               //if size of first string is higher than second
    if(l1%2==0)                                 //if size of first is even, since n in algorithm is the sizr of bigger string
    {
    k=l2-(l1/2)-1;
    a[l1/2]=b[l1/2]=d[l1/2]=c[k+1]='\0';
    flag=1;

    for(i=l1-1,j=(l1/2)-1,m=l2-1;i>=(l1/2);m--,i--,j--,k--)
    {
        a[j]=x[i-(l1/2)];
        b[j]=x[i];
        if(flag==1)
            if(l2<=l1/2)
        {
            flag=0;
            strcpy(d,y);
            strcpy(c,"0");
        }
        if(flag==1)
        {
            d[j]=y[m];
            if(k>=0)
                c[k]=y[m-(l1/2)];
        }


    }
    }
    else                                    //if size of first string odd
    {
        a[l1/2]='\0';
        b[(l1/2)+1]='\0';
        b[l1/2]=x[l1-1];
        k=l2-(l1/2)-2;
        flag=1;
        for(i=n-2,j=(n/2)-1,m=l2-2;j>=0;i--,j--,m--,k--)
        {
        a[j]=x[i-(n/2)];
        b[j]=x[i];
        if(flag==1)
            if(l2<=(l1/2)+1)
        {
            flag=0;
            strcpy(d,y);
            strcpy(c,"0");
        }
        if(flag==1)
        {
            d[j]=y[m];
            if(k>=0)
                c[k]=y[m-(l1/2)];
        }
        }
        if(flag==1)
        {
            d[(l1/2)+1]='\0';
            d[l1/2]=y[l2-1];
            c[l2-(l1/2)-1]='\0';
        }
    }

    else                                                //if second string is bigger than first
        if(l2%2==0)                                     //size of second string even
    {
    k=l1-(l2/2)-1;
    c[l2/2]=d[l2/2]=b[l2/2]=a[k+1]='\0';
    flag=1;

    for(i=l2-1,j=(l2/2)-1,m=l1-1;i>=(l2/2);m--,i--,j--,k--)
    {
        c[j]=y[i-(l2/2)];
        d[j]=y[i];
        if(flag==1)
            if(l1<=l2/2)
        {
            flag=0;
            strcpy(b,x);
            strcpy(a,"0");
        }
        if(flag==1)
        {
            b[j]=x[m];
            if(k>=0)
                a[k]=x[m-(l2/2)];
        }


    }
    }
    else                                    //size of secomd string odd
    {
        c[l2/2]='\0';
        d[(l2/2)+1]='\0';
        d[l2/2]=y[l2-1];
        k=l1-(l2/2)-2;
        flag=1;
        for(i=l2-2,j=(l2/2)-1,m=l1-2;j>=0;i--,j--,m--,k--)
        {
        c[j]=y[i-(l2/2)];
        d[j]=y[i];
        if(flag==1)
            if(l1<=(l2/2)+1)
        {
            flag=0;
            strcpy(b,x);
            strcpy(a,"0");
        }
        if(flag==1)
        {
            b[j]=x[m];
            if(k>=0)
                a[k]=x[m-(l2/2)];
        }
        }
        if(flag==1)
        {
            b[(l2/2)+1]='\0';
            b[l2/2]=x[l1-1];
            a[l1-(l2/2)-1]='\0';
        }
    }


    return;

}


//function defenition for sum
//it will give a+b to c for any size of a and b
//no zero will be in MSB


void sum(char *a, char *b, char *c)             //to find a+b=c
{

    char temp1,temp2,flag=0,i;
    temp1=strlen(a)-1;                          //index of LSB of a
    temp2=strlen(b)-1;                          //index of LSB of b
   if(temp1==temp2)                             //size of both string equal
   {
        c[temp1+2]='\0';                        //size of c=temp1+1-->extra one for carry
        for(;temp1>=0;temp1--)                  //adding individual characters
        {
        c[temp1+1]=a[temp1]+b[temp1]-48;        //adding ASCII and subtract ASCII of '0' to get difference
        if(flag==1)                             //flag=1 if there is carry from previoud addition; initially its 0
        {
            c[temp1+1]++;                       //existing carry is added and flag set to 0
            flag=0;
        }
        if(c[temp1+1]>57)                       //in case addition exceeds 10, carry will be generated
        {
            c[temp1+1]-=10;
            flag=1;
        }
        }
        if(flag==1)                             //setting up MSB
            c[0]=49;
        else
            {
                for(i=0;i                    c[i]=c[i+1];
            }

    }

    else if(temp1>temp2)                        //if size of first string is higher, follow similar steps
   {


        c[temp1+2]='\0';
        for(;temp2>=0;temp1--,temp2--)
        {
        c[temp1+1]=a[temp1]+b[temp2]-48;
        if(flag==1)
        {
            c[temp1+1]++;
            flag=0;
        }
        if(c[temp1+1]>57)
        {
            c[temp1+1]-=10;
            flag=1;
        }
        }


                for(;temp1>=0;temp1--)           //extra digits in first string is added
                {

                    c[temp1+1]=a[temp1]+flag;

                    if(c[temp1+1]>57)
                    {
                        c[temp1+1]-=10;
                        flag=1;
                    }
                    else
                        flag=0;
                }
            if(flag==1)
                c[0]='1';
            else
                for(i=0;i<strlen(c);i++)>
                    c[i]=c[i+1];


    }
     else                                       //second one is higher
   {


        c[temp2+2]='\0';
        for(;temp1>=0;temp1--,temp2--)
        {
        c[temp2+1]=a[temp1]+b[temp2]-48;
        if(flag==1)
        {
            c[temp2+1]++;
            flag=0;
        }
        if(c[temp2+1]>57)
        {
            c[temp2+1]-=10;
            flag=1;
        }
        }


                for(;temp2>=0;temp2--)            //extra digits in first string is added
                {

                    c[temp2+1]=b[temp2]+flag;

                    if(c[temp2+1]>57)
                    {
                        c[temp2+1]-=10;
                        flag=1;
                    }
                    else
                        flag=0;
                }
            if(flag==1)
                c[0]='1';
            else
                for(i=0;i<strlen(c);i++)>
                    c[i]=c[i+1];


    }

    return;
}
Posted
Updated 5-Jul-16 8:54am
v2
Comments
[no name] 5-Jul-16 6:04am    
Learning to use the debugger is the next step. This is how to find your problem(s). btw:It is "Karatsuba" named after a person.
Richard MacCutchan 5-Jul-16 7:38am    
You could simplify that to just a few lines of code with some though about exactly what you are doing. Most of what you have written is totally redundant.
pmmahesh 5-Jul-16 8:14am    
I know its too long. I have done the same in JAVA using substring() and all instead of these lengthier functions. Here I just tried to avoid in built functions or methods as much as possible. I just like to know why changing variable name and all is affecting the result.
Richard MacCutchan 5-Jul-16 8:49am    
No, I mean you should throw away all that code and start again. The problem is quite simple:
1. Read each string.
2. Parse the numbers and operator into separate tokens.
3. Convert the numbers to integers, floats as required.
4. Calculate the sum, difference etc., based on the operator.
5. Print the answer.

Also, use proper names for your variables, it will help you debug problems much more easily.
pmmahesh 7-Jul-16 2:03am    
OK, I got that. But someone told me to do all these operations in string itself, because large number operations can be done only with strings(say two 50 digit numbers). And I have got correct results when I called the function sum() from main(). For the same input , I didnt get it when I called it from the recursive function. Sorry to trouble you. I just want to know what might be the reasons for this. And also let me know how large numbers can be managed.

Your primary problem is, that you are using pointers complety incorrect. A pointer is some variable which only points to memory which has the value. It is like the address, where somebody resides. Here is some newbie explanation of pointers.

I think that your algorithm is some string manipulation but not a Karatsuba algorithm. If you want to do it this way: declare for every call new variables and fill them with actual values to avoid the pointer problematics.

For converting a string into a number you better use __ttoi. That would not only be easier, but avoid the pointer probelm. :-O
 
Share this answer
 
You should learn to use the debugger as soon as possible. Rather than guessing what your code is doing, It is time to see your code executing and ensuring that it does what you expect.

The debugger allow you to follow the execution line by line, inspect variables and you will see that there is a point where it stop doing what you expect.
Debugger - Wikipedia, the free encyclopedia[^]
Mastering Debugging in Visual Studio 2010 - A Beginner's Guide[^]

you will see your code perform and probably where it go wrong.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900