Thursday, November 07, 2019

[pprmvgii] 128-bit multiplication in C++

/*
Demonstration of multiplying two 64-bit integers to get a 128-bit result in C++ (gcc).

./a.out 0xdeadbeefdeadbeef 12345678901234567890

Input arguments (parsed by strtoul) may be specified in hexdecimal (with 0x prefix) or decimal or octal (with 0 prefix).

This code is public domain.
*/

// define this to test that the relevant types exist as builtins, without any include files
//#define TYPESONLY

#ifndef TYPESONLY
#include <cstdlib>
#include <cassert>
#include <iostream>
using std::endl;
using std::cout;
#endif

int main(int argc, char**argv){
#ifndef TYPESONLY
assert(argc>2);
assert(sizeof(unsigned long)==8);
#endif
// uint64_t is also available in <cstdint>
unsigned long x;
unsigned long y;
#ifndef TYPESONLY
x= strtoul(argv[1],0,0);
y= strtoul(argv[2],0,0);
cout << x << " * " << y << endl << "=" << endl;
#endif

unsigned __int128 zfull=static_cast<unsigned __int128 >(x) * static_cast<unsigned __int128 >(y);
// __uint128_t is also available as a builtin, though some documentation says <cstdint>

unsigned long zhi = zfull >> 64;
unsigned long zlo = zfull; // get lower bits via truncation

unsigned long test=x*y;
#ifndef TYPESONLY
assert(test==zlo);

// cout does not support 128-bit.
// This output format can be cut and pasted into an arbitrary precision calculator.

cout << zhi << " *2^64+ " << zlo << endl;
#endif
}

No comments :