Take the 2-minute tour ×

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...

share|improve this question
If you need specifically 128-bit numbers, then that would be the way to go (unless you can find a library which has already done it for you, of course). But it sounds like you really want integers of arbitrary length, in which case a bigint library would make more sense. –  jalf Jul 27 '09 at 15:52
I don't think he wants bigint. With arbitrary length comes a lot of overhead and complexity. He's probably just looking for a nice portable solution that would work for >128 in theory even if it's never needed. –  Draemon Jul 27 '09 at 15:55
I added the >128 comment in an effort to make the question more generally relevant. I don't need it at this time. –  David Coufal Jul 27 '09 at 16:14

8 Answers 8

up vote 7 down vote accepted

Look into other libraries that have been developed. Lots of people have wanted to do this before you. :D

Try bigint C++

share|improve this answer
Just a bit of warning, bigint C++ is under GPL v2 –  Erbureth Aug 16 '13 at 17:24

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);
share|improve this answer
Ah, the random downvote nearly 3 years after posting. Gotta love it. –  Evan Teran Jan 17 '12 at 23:09
+1 @Evan Teran Here's your upvote for that freaked up guys's downvote :) –  Shekhar_Pro Mar 15 '12 at 10:33
Could you make this class without boost ? I think including boost defeats the whole point of being "lightweight", and probably why of those downvoters and why this isnt accepted answer. –  Rookie Jan 1 '13 at 10:03
Hey Rookie... what part of "unsigned" do you not understand ;) –  user1356386 Jan 16 '13 at 20:45
@BradTilley at first I thought you were insulting him... then I saw his name... nice. –  justnS Jan 30 '13 at 2:11

This is somewhat of a special case, especially since you didn't specify what platform(s) you're looking for, but with GCC you can use what is called mode(TI) to get (synthesized) 128-bit operations, for instance:

   typedef unsigned int uint128_t __attribute__((mode(TI)));

   uint64_t x = 0xABCDEF01234568;
   uint64_t y = ~x;

   uint128_t result = ((uint128_t) x * y);

   printf("%016llX * %016llX -> ", x, y);

   uint64_t r1 = (result >> 64);
   uint64_t r2 = result;

   printf("%016llX %016llX\n", r1, r2);

This only works on 64-bit processors, though.

One way or another, you're looking at multiple precision arithmetic to solve this. mode(TI) will cause the compiler to generate the operations for you, otherwise they have to be written explicitly.

You can use a general bigint package; ones in C++ I know of include the number theory packages LiDIA and NTL, and the bigint packages used for cryptographic code in Crypto++ and Botan). Plus of course there is GnuMP, which is the canonical C MPI library (and it does have a C++ wrapper as well, though it seemed poorly documented last time I looked at it). All of these are designed to be fast, but are also probably tuned for larger (1000+ bit) numbers, so at 128 bits you may be dealing with a lot of overhead. (On the other hand you don't say if that matters or not). And all of them (unlike the bigint-cpp package, which is GPL, are either BSD or LGPL) - not sure if it matters - but it might matter a lot.

You could also write a custom uint128_t kind of type; typically such a class would implement much the same algorithms as a regular MPI class, just hardcoded to have only 2 or 4 elements. If you are curious how to implement such algorithms, a good reference is Chapter 14 of the Handbook of Applied Cryptography

Of course doing this by hand is easier if you don't actually need all the arithmetic operations (division and modulo, in particular, are rather tricky). For instance, if you just need to keep track of a counter which might hypothetically overflow 64 bits, you could just represented it as a pair of 64 bit long longs and do the carry by hand:

unsigned long long ctrs[2] = { 0 };

void increment() {
   if(!ctrs[0]) // overflow

Which of course is going to be a lot simpler to deal with than a general MPI package or a custom uint128_t class.

share|improve this answer

Don't reinvent the wheel -- I'm positive other people have already solved this problem, although I can't name any solutions off the top of my head. GMP can surely solve your problem, although it's overkill for fixed-size integers, and it's also a little cumbersome to use (it's a C library, not C++).

share|improve this answer
GNUMP contains a C++ wrapper. –  Axel Gneiting Aug 2 '10 at 13:46

You may want to try GMP

share|improve this answer

Here is a library I found on google.


share|improve this answer

You might be better off with an infinite-precision integer class, rather than a sequence of increasing size. Some languages (like Common Lisp and IIRC Python) have them natively. I'm not sure offhand what's available for C++; last I looked there wasn't a Boost version.

share|improve this answer

In Visual Studio C++ there is a type FLOAT128 that is used to represent 128-bit integers. It is implemented as:

#if defined(_M_IA64) && !defined(MIDL_PASS)
typedef struct _FLOAT128 {
    __int64 LowPart;
    __int64 HighPart;
} FLOAT128;

so I'm not sure about what math operations are implemented for it

share|improve this answer
Are you sure that a type called FLOAT is used to represent INTEGERS? Doesn't make much sense. –  fortran Jul 27 '09 at 16:25
It's called FLOAT but it's composed of two 64-bit ints. The name doesn't make sense to me either, there's probably some historical reason for the misleading name. –  Jeff Leonard Aug 3 '09 at 3:25
Put a big 64-bit integer (greater than 53 bits) into a 64-bit double and see what happens. –  user1356386 Jan 16 '13 at 20:50

Your Answer


