Created
February 26, 2016 10:41
-
-
Save kebunit/4fa83273090837fc1157 to your computer and use it in GitHub Desktop.
FAST C/C++ Implementation of the Karatsuba Multiplication algorithm. This is the only C++ implementation that I found online that uses straight C++ primitives to store data instead of std::vector or std::string objects. Because of this, it's pretty speedy. You can use this file in your program
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//============================================================================ | |
// Name : KaratsubaMultiplication.cpp | |
// Author : Evin Ugur (http://evinugur.com) | |
// Version : 1.0 | |
// Copyright : Copyright 2015. You can use this code however and wherever you want no strings attached | |
// Description : C++ Functions to Perform Karatsbuba Multiplications | |
//============================================================================ | |
#include <iostream> | |
#include <math.h> | |
#include "KaratsubaMultiplication.h" | |
using namespace std; | |
int getLength(long long value) { | |
int counter = 0; | |
while (value != 0) { | |
counter++; | |
value /= 10; | |
} | |
return counter; | |
} | |
long long multiply(long long x, long long y) { | |
int xLength = getLength(x); | |
int yLength = getLength(y); | |
// the bigger of the two lengths | |
int N = (int)(fmax(xLength, yLength)); | |
// if the max length is small it's faster to just flat out multiply the two nums | |
if (N < 10) | |
return x * y; | |
//max length divided and rounded up | |
N = (N/2) + (N%2); | |
long long multiplier = pow(10, N); | |
long long b = x/multiplier; | |
long long a = x - (b * multiplier); | |
long long d = y / multiplier; | |
long long c = y - (d * N); | |
long long z0 = multiply(a,c); | |
long long z1 = multiply(a + b, c + d); | |
long long z2 = multiply(b, d); | |
return z0 + ((z1 - z0 - z2) * multiplier) + (z2 * (long long)(pow(10, 2 * N))); | |
} | |
// C++ example (uses cout...) | |
// (this code works in straight C too though if you use a different main function) | |
int main() { | |
// two numbers | |
long long a = 2406994; | |
long long b = 2328563; | |
cout << multiply(a,b) << endl; | |
return 0; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* KaratsubaMultiplication.h | |
* | |
* Created on: Feb 4, 2015 | |
* Author: Evin Ugur (http://evinugur.com) | |
*/ | |
#ifndef KARATSUBAMULTIPLICATION_H_ | |
#define KARATSUBAMULTIPLICATION_H_ | |
int getLength(long long value); // returns the number of digits a number has | |
long long multiply(long long x, long long y); // Karatsuba multiplication of two numbers | |
#endif /* KARATSUBAMULTIPLICATION_H_ */ |
In line 33, it should be
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
By necessity you need integer arrays to perform multiplications large enough to obtain any optimization from using Karatsuba. How people think this code is fast (or actually does anything) is beyond me. It's theorectically impossible to write karatsuba algorithm faster than naive multiplication with only two 64-bit numbers; it requires at least two numbers of 5 radix_n length, any less requires more operations than long multiplication. Because multiplication of 64bit is executable as single instruction you can treat it as the radix instead of using ten or any other smaller (and therefore wasteful) number.