I believe there isn't any portable standard data type for 128 bits of data. So, my question is about how efficiently 64 bit operations can be carried out without loss of data using existing standard data-types.
For example : I have following two uint64_t type variables:
uint64_t x = -1; uint64_t y = -1;
Now, how the result of mathematical operations such as x+y, x-y, x*y and x/y
can be stored/retrieved/printed ?
For above variables, x+y results in value of -1 which is actually a 0xFFFFFFFFFFFFFFFFULL with a carry 1.
void add (uint64_t a, uint64_t b, uint64_t result_high, uint64_t result_low)
{
result_low = result_high = 0;
result_low = a + b;
result_high += (result_low < a);
}
How other operations can be performed as like add
, which gives proper final output ?
I'd appreciate if someone share the generic algorithm which take care of overflow/underflow etcetera that might comes into picture using such operations.
Any standard tested algorithms which might can help.
You can emulate
uint128_t
if you don't have it:Multiplication without inbuilt compiler or assembler support is a bit more difficult to get right. Essentially, you need to split both multiplicands into hi:lo unsigned 32-bit, and perform 'long multiplication' taking care of carries and 'columns' between the partial 64-bit products.
Divide and modulo return 64 bit results given 64 bit arguments - so that's not an issue as you have defined the problem. Dividing 128 bit by 64 or 128 bit operands is a much more complicated operation, requiring normalization, etc.
longlong.h
routinesumul_ppmm
andudiv_qrnnd
in GMP give the 'elementary' steps for multiple-precision/limb operations.There are lot of
BigInteger
libraries out there to manipulate big numbers.If you want to avoid library integration and your requirement is quite small, here is my basic
BigInteger
snippet that I generally use for problem with basic requirement. You can create new methods or overload operators according your need. This snippet is widely tested and bug free.Source
Usage
In most of the modern GCC compilers
__int128
type is supported which can hold a 128 bit integers.Example,