
Data Structure
Networking
RDBMS
Operating System
Java
MS Excel
iOS
HTML
CSS
Android
Python
C Programming
C++
C#
MongoDB
MySQL
Javascript
PHP
- Selected Reading
- UPSC IAS Exams Notes
- Developer's Best Practices
- Questions and Answers
- Effective Resume Writing
- HR Interview Questions
- Computer Glossary
- Who is Who
Implement Schonhage-Strassen Algorithm for Multiplication of Two Numbers in Java
The Schonhage-Strassen algorithm is useful when we need to multiply large decimal numbers. As Java supports the 1018 size of integers, and if we need to multiply the digits of more than 1018, we need to use the Schonhage-Strassen algorithm, as it is one of the fastest multiplication algorithms.
It uses the basic rules for the multiplication of two numbers. It first performs the linear convolution and then performs the carry to get the final result.
Problem statement - We have given mul1 and mul2 large decimal numbers and need to implement the Schonhage-Strassen algorithm to multiply both numbers.
Sample examples
Input
mul1 = 320; = 760;
Output
243200
Explanation - It has multiplied both numbers.
Input
mul1 = 32012233; = 76031232;
Output
1612188928
Explanation - It has multiplied two large decimal numbers.
Approach 1
We will first write a function to calculate the linear convolution in this approach. After that, we will add all resultant values of linear convolutions in such a way so that we can forward carry to add into the next element.
Here, we have explained a step-by-step algorithm to write Java code for the Schonhage-Strassen algorithm.
Algorithm
Step 1 - Execute the perfromMultiplication() function. In the function, execute the getLinConvolution() function first.
Step 2 - In the getLinConvolution() function, count the total digits of the given number using the findTotalDigits() function.
Step 2.1 - In the findTotalDigits() function, initialize 'cnt' with zero to store the total digits of the number.
Step 2.2 -Make iterations until num_int is greater than zero.
Step 2.3 - In the loop, divide the num_int by 10. Also, increase the value of cnt by 1.
Step 2.3 - At the end, return the 'cnt' value.
Step 3 - Define 'tmp_mul1' and store the value of the mul1 number. Also, define the lcon_len variable to store the length of the array, which we need to use to store linear convolutions.
Step 4 - Start traversing the digits of mul2. In the loop, store the value of tmp_mul1 to mul1 and use another nested loop to traverse the digits of mul1.
Step 5 - Update the value at (p + q)th index in the array by adding (mul2 % 10) * (mul1 % 10) to the current value.
Step 6 - Now, we have linear convolution and need to perform the carry on the list. So, call the addCarry() function.
Step 7 - Initialize the variables to store product, carry, and base.
Step 8 - Start traversing the list. Add 'C' to the value ith index value in the list.
Step 9 - In the 'predocut_res' add B * (linConvoList[i] % 10), where B is the base value.
Step 10 - Divide linConvoList by 10, and update the value of 'C' with it.
Step 11 - Multiply base with 10.
Step 12 - Once all loop iterations are completed, add C*B into the product result to add the final carry to the list. Finally, print the product_res, a product of two decimal numbers.
Example
import java.io.*; public class Main { // for storing the LinearConvolution static int[] linConvoList; // to store length of the LinearConvolution static int lcon_len; // function to count total digits in given number static int findTotalDigits(long num_int) { // Initial digits int cnt = 0; // Make iterations until num_int is greater than zero while (num_int > 0) { num_int /= 10; cnt++; } // return cnt value return cnt; } static void getLinConvolution(long mul1, long mul2) { // count digits in mul1 int mul1Digits = findTotalDigits(mul1); // count digits in mul2 int mul2Digits = findTotalDigits(mul2); // to store temporary value of mul1 long tmp_mul1 = mul1; // Initialize the length of the linear convolution lcon_len = mul1Digits + mul2Digits - 1; // Initialize the list linConvoList = new int[lcon_len]; // Filling the linConvoList array for (int p = 0; p < mul2Digits; p++, mul2 /= 10) { // Reset the value of mul1 for each iteration of mul2 mul1 = tmp_mul1; for (int q = 0; q < mul1Digits; q++, mul1 /= 10) { // multiply digit of mul1 and mul2 linConvoList[p + q] += (int) ((mul2 % 10) * (mul1 % 10)); } } System.out.print("The values stored in the linear convolution array are: "); for (int p = lcon_len - 1; p >= 0; p--) { System.out.print(linConvoList[p] + " "); } System.out.println(); } static void addCarry() { // initialize product to 0 long product_res = 0; // Initialize variables for carry and base int C = 0, B = 1; // Traverse the list for (int i = 0; i < lcon_len; i++) { linConvoList[i] += C; // performing operations product_res = product_res + (B * (linConvoList[i] % 10)); // Divide the linConvoList[i] by 10 to get carry C = linConvoList[i] / 10; // Multiply the base by 10 B *= 10; } // Add the final carry if it exists product_res += C * B; System.out.println("\nThe Product of mul1 and mul2 is: " + product_res+ "\n"); } // Multiplication starts here static void performMultiplication(long mul1, long mul2) { // To get the LinearConvolution getLinConvolution(mul1, mul2); // Add carry to the LinearConvolution addCarry(); } // Driver method public static void main(String[] args) { long mul1, mul2; // long numbers to multiply mul1 = 320; mul2 = 760; performMultiplication(mul1, mul2); } }
Output
The values stored in the linear convolution array are: 21 32 12 0 0 The Product of mul1 and mul2 is: 243200
Time complexity - O(M + N), where M is the total number of digits in mul1, and N is the total number of digits in mul2.
Space complexity - O(M + N), as store linear convolutions.
In the code, programmers can observe that the Schonhage-Strassen algorithm works the same as the normal multiplication we do in mathematics. Programmers can observe the result of linear convolutions to understand the algorithm.
Also, programmers should try to write algorithms to sum two large numbers for more practice.