Is there a 128 bit integer in C++?

93,658

Solution 1

GCC and Clang support __int128

Solution 2

Although GCC does provide __int128, it is supported only for targets (processors) which have an integer mode wide enough to hold 128 bits. On a given system, sizeof() intmax_t and uintmax_t determine the maximum value that the compiler and the platform support.

Solution 3

Checkout boost's implementation:

#include <boost/multiprecision/cpp_int.hpp>

using namespace boost::multiprecision;

int128_t v = 1;

This is better than strings and arrays, especially if you need to do arithmetic operations with it.

Solution 4

Your question has two parts.

1.128-bit integer. As suggested by @PatrikBeck boost::multiprecision is good way for really big integers.

2.Variable to store UUID / GUID / CLSID or whatever you call it. In this case boost::multiprecision is not a good idea. You need GUID structure which is designed for that purpose. As cross-platform tag added, you can simply copy that structure to your code and make it like:

struct GUID
{
    uint32_t Data1;
    uint16_t Data2;
    uint16_t Data3;
    uint8_t  Data4[8];
};

This format is defined by Microsoft because of some inner reasons, you can even simplify it to:

struct GUID
{
    uint8_t Data[16];
};

You will get better performance having simple structure rather than object that can handle bunch of different stuff. Anyway you don't need to do math with GUIDS, so you don't need any fancy object.

Solution 5

I would recommend using std::bitset<128> (you can always do something like using UUID = std::bitset<128>;). It will probably have a similar memory layout to the custom struct proposed in the other answers, but you won't need to define your own comparison operators, hash etc.

Share:
93,658
danijar
Author by

danijar

Researcher aiming to build intelligent machines based on concepts of the human brain. Website · Twitter · Scholar · Github

Updated on January 27, 2022

Comments

  • danijar
    danijar over 2 years

    I need to store a 128 bits long UUID in a variable. Is there a 128-bit datatype in C++? I do not need arithmetic operations, I just want to easily store and read the value very fast.

    A new feature from C++11 would be fine, too.

  • Jesse Good
    Jesse Good over 10 years
    Boost also has a uuid library btw.
  • danijar
    danijar over 10 years
    @JesseGood I may use that library, but I'd like store the ids in a standard type.
  • Kurt Pattyn
    Kurt Pattyn over 10 years
    Regarding boost, you can also have a look at this post: stackoverflow.com/a/16218841/52568
  • Jesse Good
    Jesse Good over 10 years
    @danijar: What "standard"? boost uses uint8_t data[16]; while libuuid is unsigned char data[16];, all libraries I know use arrays.
  • danijar
    danijar over 10 years
    @JesseGood Okay, I didn't knew that. Then this is fine. The only challenge might be to use it as key in an std::unordered_map. I am not sure if arrays can be used without providing my own hash function.
  • Jesse Good
    Jesse Good over 10 years
    @danijar: That's not too difficult, see the answer here.
  • James Kanze
    James Kanze over 10 years
    @JesseGood Curious as to why they would use uint8_t. There are only two operations (other than copy and assignment) which make sense on a UUID: comparison for equality, and conversion to a string. The larger the basic type, the faster the comparison (up to a point), and the string format of the UUID suggests uint16_t. So uint16_t or larger would seem to be in order.
  • Jesse Good
    Jesse Good over 10 years
    @JamesKanze: I'm not 100 percent sure, but byte-ordering would be a factor since uuids are often used in network messaging.
  • James Kanze
    James Kanze over 10 years
    @JesseGood Good point. That probably explains it. (In all of the cases where I've used UUID, they've ended up in text files, so the byte order has been irrelevant.)
  • MFH
    MFH over 10 years
    @JamesKanze: The type of storage should be negligible as UUIDs are fixed size and can therefor be compared via std::memcmp. (assuming that the byte-order of both UUIDs is equal [which it should be anyways])
  • James Kanze
    James Kanze over 10 years
    @MFH But memcmp will probably be less than optimal for the comparison. (Whether that's relevant or not is another question.)
  • MFH
    MFH over 10 years
    @JamesKanze: I'd say that's a question of implementation. There is nothing preventing a 100% standard compatible version to reinterpret the pointers as const unsigned long long when count == 2 * sizeof(unsigned long long). If it does that than it will actually be able to compare both UUIDs with 4 read operations and 2 compares. But even if it doesn't do that it will still very likely be extremely fast due to caching.
  • CppNoob
    CppNoob over 8 years
    Upvoted because it points out an issue with the accepted answer.
  • Peter Cordes
    Peter Cordes about 8 years
    This isn't quite correct: __int128_t is supported on x86-64 (but not i386). It's implemented in 64bit integer registers using addition-with-carry, and extended-precision code for shifts, multiplies, and so on. (The 128b SSE vector registers aren't useful for anything except boolean (AND/OR/XOR), because they can't do a single 128b add. SSE can do two 64b adds, or multiple smaller elements).
  • user3342339
    user3342339 about 8 years
    only for 64-bit architectures, though. See gcc.gnu.org/onlinedocs/gcc/_005f_005fint128.html
  • user1418199
    user1418199 about 8 years
    boost::multiprecision::int128_t seems to have performance issues compared against __int128_t. {code} #include "vlib/stopwatch.hpp" #include <iostream> #include <string> #include <boost/multiprecision/cpp_int.hpp> using namespace std; int main(int , char **argv) { size_t cnt = std::stoull(argv[1]); __int128_t counter = 0; for(size_t i = 0; i < cnt; ++i) { ++counter; counter <<= 2; } } {code} boost takes 20x the time on this code.
  • HolyBlackCat
    HolyBlackCat over 5 years
    There is no such template in the standard library. What library are you talking about?
  • Admin
    Admin over 4 years
    Non 64-bit desktops are very rare and if your arduino would totally ever need 128bits to store a single value that's a different topic. @user3342339
  • einpoklum
    einpoklum about 4 years
    Is there a preprocessor define such as HAVE_INT_128_T or something similar we could check?
  • phuclv
    phuclv about 4 years
    the pair is EDX:EAX or RDX:RAX. There's no RAX:EAX pair.