int long_value[] = { 9, 8, 7, 6, 5, 4} // 456789
* This source code was highlighted with Source Code Highlighter .
- #include <cstring>
- #define BASE 10 // number system
- #define MIN_LENGTH_FOR_KARATSUBA 4 // numbers are shorter multiplied by a quadratic algorithm
- typedef int digit; // taken only for digits
- typedef unsigned long int size_length; // type for long numbers
- using namespace std;
- struct long_value { // type for long numbers
- digit * values; // array with numbers written in reverse order
- size_length length; // is long numbers
- };
- long_value sum (long_value a, long_value b) {
- / * function to add two long numbers. If numbers of different length are added together.
- * then the longer is passed as the first argument. Returns new
- * unnormalized number.
- * /
- long_value s;
- s.length = a.length + 1;
- s.values ββ= new digit [s.length];
- s.values ββ[a.length - 1] = a.values ββ[a.length - 1];
- s.values ββ[a.length] = 0;
- for (size_length i = 0; i <b.length; ++ i)
- s.values ββ[i] = a.values ββ[i] + b.values ββ[i];
- return s;
- }
- long_value & sub (long_value & a, long_value b) {
- / * function to subtract one long number from another. Changes the contents of the first
- * numbers. Returns a link to the first number. The result is not normalized.
- * /
- for (size_length i = 0; i <b.length; ++ i)
- a.values ββ[i] - = b.values ββ[i];
- return a;
- }
- void normalize (long_value l) {
- / * Normalization of the number - bringing each digit in accordance with the number system.
- *
- * /
- for (size_length i = 0; i <l.length - 1; ++ i) {
- if (l.values ββ[i]> = BASE) { // if the number is greater than the maximum, then a transfer is organized
- digit carryover = l.values ββ[i] / BASE;
- l.values ββ[i + 1] + = carryover;
- l.values ββ[i] - = carryover * BASE;
- } else if (l.values ββ[i] <0) { // if less - loan
- digit carryover = (l.values ββ[i] + 1) / BASE - 1;
- l.values ββ[i + 1] + = carryover;
- l.values ββ[i] - = carryover * BASE;
- }
- }
- }
- long_value karatsuba (long_value a, long_value b) {
- long_value product; // resulting product
- product.length = a.length + b.length;
- product.values ββ= new digit [product.length];
- if (a.length <MIN_LENGTH_FOR_KARATSUBA) { // if the number is shorter then apply a naive multiplication
- memset (product.values, 0, sizeof (digit) * product.length);
- for (size_length i = 0; i <a.length; ++ i)
- for (size_length j = 0; j <b.length; ++ j) {
- product.values ββ[i + j] + = a.values ββ[i] * b.values ββ[j];
- / * If you change MIN_LENGTH_FOR_KARATSUBA or BASE, uncomment the following
- * lines and pick up acc. values ββfor avoiding overflow discharges.
- * For example, for the decimal number system, the number 100 means that it is organized
- * transfer 1 through one digit, 200 - transfer 2 through one digit, 5000 - 5 through two.
- * if (product.values ββ[i + j]> = 100) {
- * product.values ββ[i + j] - = 100;
- * product.values ββ[i + j + 2] + = 1;
- *}
- * /
- }
- } else { // multiplication by the Karatsuba method
- long_value a_part1; // the younger part of a
- a_part1.values ββ= a.values;
- a_part1.length = (a.length + 1) / 2;
- long_value a_part2; // the upper half of a
- a_part2.values ββ= a.values ββ+ a_part1.length;
- a_part2.length = a.length / 2;
- long_value b_part1; // the younger part of the number b
- b_part1.values ββ= b.values;
- b_part1.length = (b.length + 1) / 2;
- long_value b_part2; // the highest part of the number b
- b_part2.values ββ= b.values ββ+ b_part1.length;
- b_part2.length = b.length / 2;
- long_value sum_of_a_parts = sum (a_part1, a_part2); // sum of the parts of a
- normalize (sum_of_a_parts);
- long_value sum_of_b_parts = sum (b_part1, b_part2); // sum of parts of number b
- normalize (sum_of_b_parts);
- long_value product_of_sums_of_parts = karatsuba (sum_of_a_parts, sum_of_b_parts);
- // product of parts sums
- long_value product_of_first_parts = karatsuba (a_part1, b_part1); // junior member
- long_value product_of_second_parts = karatsuba (a_part2, b_part2); // senior member
- long_value sum_of_middle_terms = sub (sub (product_of_sums_of_parts, product_of_first_parts), product_of_second_parts);
- // find the sum of average members
- / *
- * Summation of a polynomial
- * /
- memcpy (product.values, product_of_first_parts.values,
- product_of_first_parts.length * sizeof (digit));
- memcpy (product.values ββ+ product_of_first_parts.length,
- product_of_second_parts.values, product_of_second_parts.length
- * sizeof (digit));
- for (size_length i = 0; i <sum_of_middle_terms.length; ++ i)
- product.values ββ[a_part1.length + i] + = sum_of_middle_terms.values ββ[i];
- / *
- * Stripping
- * /
- delete [] sum_of_a_parts.values;
- delete [] sum_of_b_parts.values;
- delete [] product_of_sums_of_parts.values;
- delete [] product_of_first_parts.values;
- delete [] product_of_second_parts.values;
- }
- normalize (product); // final number normalization
- return product;
- }
Source: https://habr.com/ru/post/124258/