- Data Structure
- Networking
- RDBMS
- Operating System
- Java
- MS Excel
- iOS
- HTML
- CSS
- Android
- Python
- C Programming
- C++
- C#
- MongoDB
- MySQL
- Javascript
- PHP
- Physics
- Chemistry
- Biology
- Mathematics
- English
- Economics
- Psychology
- Social Studies
- Fashion Studies
- Legal Studies
- Selected Reading
- UPSC IAS Exams Notes
- Developer's Best Practices
- Questions and Answers
- Effective Resume Writing
- HR Interview Questions
- Computer Glossary
- Who is Who
Karatsuba Algorithm for Fast Multiplication of Large Decimal Numbers Represented as Strings
We are not able to store the large decimal numbers in normal data types such as the int or even in long long, so we store them in the string. When we multiply two integers represented in the form of a string it takes a lot of time more specifically N*M where N is the size of the given string. In this article, we will implement Karatsuba Algorithm for the fast Multiplication of large decimal numbers represented as strings.
Input
string num1 = "34984" string num2 = "937488"
Output
32797080192
Explanation
We will see the algorithm for the multiplication.
Karatsuba Algorithm
According to this algorithm, we are going to make both the strings of the same length (by adding some extra zeros in the front of the smallest number) and we need the length of both the strings of even size, so if large size string is not of even length, then we can add one extra zero in front of it.
Now, we can break both numbers as:
$\mathrm{N_{1}=10^{N/2}*Nl_{1}+Nr_{1}}$here Nl1 represents the first n/2 digits of the given number and NR1 represents the last n/2 digits of the given number, means we have divided the current number into two equal parts.
For example: 1234 can be written as $(\mathrm{12\:*10^2\:+\:34})$.
Similarly, the second number is written as:
$\mathrm{N_{2}=10^{N/2}*Nl_{2}+Nr_{2}}$
Now, the product of these two numbers is:
$\mathrm{=>N_{1}*N_{2}=(10^{n/2}*Nl_{1}+Nr_{1})*(10^{n/2}*Nl_{2}+Nr_{2})}$
$\mathrm{=(10^{n}*Nl_{1}*Nl_{2})+10^{n/2}((Nl_{2}*Nr_{1})+(Nl_{1}*Nr_{2}))+(Nr_{2}*Nr_{1})}$
$\mathrm{=>(Nl_{2}*Nr_{1})+(Nl_{1}*Nr_{2})}$ can be written as
$\mathrm{=(Nl_{1}*Nr_{1})*(Nl_{2}*Nr_{2})-(Nl_{1}*Nr_{1})-(Nl_{2}*Nr_{2})}$
So, our final equation is:
$\mathrm{=>N_{1}*N_{2}=(10^{n}*Nl_{1}*Nl_{2})+(Nr_2*Nr_1)+10^{n/2}((Nl_{1}*Nr_{1})*(Nl_{2}*Nr_{2})-(Nl_{1}*Nr_{1})-(Nl_{2}*Nr_{2}))} $
From the above equation, we can see that we have to just make only three multiplications instead of four multiplications we have to just do the three and we have to go recursively which makes the recursive equation in the form of
$$\mathrm{=>T(n)=3T(n/2)+O(n)}$$
Example
#include <bits/stdc++.h> using namespace std; // creating a function to get the addition of the integers passed as parameters in the form of the string string Sum(string str1, string str2){ // for easy processing, making second string greater if (str1.size() > str2.size()){ swap(str2,str1); } string sum = ""; // string to store the sum int len1 = str1.length(); // variable to get the size of the first string int len2 = str2.length(); // variable to get the size of the second string // reversing both strings to get the sum reverse(str1.begin(), str1.end()); reverse(str2.begin(), str2.end()); int carry = 0; // variable to store the carry // traversing over the first string for (int i = 0; i< len1; i++){ int temp = ((str1[i] - '0') + (str2[i] - '0') + carry); sum.push_back(temp % 10 + '0'); carry = temp / 10; } // traversing over the second string for (int i = len1; i< len2; i++){ int temp = ((str2[i] - '0') + carry); sum.push_back(temp % 10 + '0'); carry = temp / 10; } // if carry is not zero if (carry){ sum.push_back(carry + '0'); } // reverse the sum string reverse(sum.begin(), sum.end()); return sum; } // create a function to find the difference between the given numbers string Diff(string str1, string str2){ string ans = ""; // string to store the answer // getting length of both the strings int len1 = str1.length(); int len2 = str2.length(); // reversing both the given strings reverse(str1.begin(), str1.end()); reverse(str2.begin(), str2.end()); int carry = 0; // traversing over the second string and subtracting the first string for (int i = 0; i< len2; i++){ int temp = ((str1[i] - '0') - (str2[i] - '0') - carry); // if the subtraction value is less than 0 then add 10 into the variable sub and mark the carry as 1 if (temp < 0) { temp = temp + 10; carry = 1; } else{ carry = 0; } ans.push_back(temp + '0'); } // subtracting the carry from the greater number for (int i = len2; i< len1; i++) { int temp = ((str1[i] - '0') - carry); // If the sub value is -ve, then make it positive if (temp < 0) { temp = temp + 10; carry = 1; } else{ carry = 0; } ans.push_back(temp + '0'); } reverse(ans.begin(), ans.end()); // reversing the ans string return ans; // Return answer } // creating the function for removal of the zeroes string removeZeros(string s){ // using regex pattern to remove the zeroes const regex pattern("^0+(?!$)"); s = regex_replace(s, pattern, ""); return s; } // creating the function to multiply the given numbers string multiply(string num1, string num2){ if (num1.length() > num2.length()){ swap(num1,num2); // getting the second string with greater size } // getting length of the numbers and making their size equal int len1 = num1.length(), len2 = num2.length(); while (len2 > len1) { num1 = "0" + num1; len1++; } // if their size is one implement the base condition if (len1 == 1) { // converting to numbers and returning the results int res = stoi(num1) * stoi(num2); return to_string(res); } // makking length odd for the strings if (len1 % 2 == 1) { len1++; num1 = "0" + num1; num2 = "0" + num2; } // defining different types of strings that are needed according to the equaltion string N1l, N1r, N2l, N2r; // finding the values of all the above strings for (int i = 0; i< len1 / 2; i++){ N1l += num1[i]; N2l += num2[i]; N1r += num1[len1 / 2 + i]; N2r += num2[len1 / 2 + i]; } // recursively calling to the function, to get the required product getting the value of N1l * N2l string a = multiply(N1l, N2l); // getting the value of N1r * N2r string b = multiply(N1r, N2r); // gettign the value of the third condition string c = Diff(multiply(Sum(N1l, N1r), Sum(N2l, N2r)),Sum(a, b)); // Multiply a by 10^len1 by adding zeroes in the end of a for (int i = 0; i< len1; i++){ a = a + "0"; } // Multiply b by 10^(len1/2) by adding zeroes in the end of b for (int i = 0; i< len1 / 2; i++){ c = c + "0"; } // getting sum of all the given strings string res = Sum(a, Sum(b, c)); // Remove leading zeroes from the result res = removeZeros(res); return res; } int main(){ string num1 = "34984"; string num2 = "937488"; // calling the function cout<<"The multiplication value of the given numbers is " <<multiply(num1,num2)<<endl; return 0; }
Output
The multiplication value of the given numbers is 32797080192
Conclusion
In this tutorial, we have implemented Karatsuba Algorithm for the fast Multiplication of large decimal numbers represented as strings. When we multiply two integers represented in the form of a string it takes a lot of time more specifically N*M where N is the size of the given string. Karatsuba Algorithm takes O(N^(1.59)) time.