What's the best way to represent a 128-bit number in C++? It should behave as closely to the built-in numeric types as possible (i.e. support all the arithmetic operators, etc).
I was thinking of building a class that had 2 64 bit or 4 32 bit numbers. Or possibly just creating a 128 bit block of memory and doing everything myself.
Is there some easier/more standard way, or something that I'm less likely to screw up when implementing it myself? :)
It would also be nice if it could be extended to 256-bit, 512-bit, etc...
In the same way that compilers emulate e.g. 64-bit integer arithmetic on architectures with register sizes less than 64 bits, some compilers also support 128-bit integer arithmetic. For example, the GCC C compiler 4.6 and later has a 128-bit integer type __int128 for some architectures.
DrinkMoreBoilingWater's blog. As an extension the integer scalar type __int128 is supported for targets which have an integer mode wide enough to hold 128 bits. Simply write __int128 for a signed 128-bit integer, or unsigned __int128 for an unsigned 128-bit integer.
The 128-bit data type can handle up to 31 significant digits (compared to 17 handled by the 64-bit long double). However, while this data type can store numbers with more precision than the 64-bit data type, it does not store numbers of greater magnitude.
If you only need to store it then you can store it in a byte array like "char num128[16]". If you need to manipulate it you need to use big numbers library like GMP. Show activity on this post. It is not possible to store it in one primitive data type, so we have to be slightly more creative.
EDIT: when I first wrote this boost::multiprecision::uint128_t
wasn't a thing yet. Keeping this answer for historical reasons.
I've made a uint128 class before, you can check it out at: http://www.codef00.com/code/uint128.h.
It is dependent on boost for automatically providing all of the variants of the math operators, so it should support everything a native unsigned int
type does.
There are some minor extensions to built in types such as initializing it with a string like this:
uint128_t x("12345678901234567890");
There is a convenience macro which works similary to the ones in C99 which you can use like this:
uint128_t x = U128_C(12345678901234567890);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With