Is there a 128 bit integer in C++?

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.

GCC and Clang support __int128

Is there a 128 bit integer in gcc?, Am I doing something wrong or is this a bug in gcc? The problem is in 47942806932686753431 part, not in __uint128_t p . According to gcc docs there's no way� A 128-bit integer type is only ever available on 64-bit targets, so you need to check for availability even if you have already detected a recent GCC version. In theory gcc could support TImode integers on machines where it would take 4x 32-bit registers to hold one, but I don't think there are any cases where it does.

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.

Assigning 128 bit integer in C, 6.9 128-bit Integers. As an extension the integer scalar type __int128 is supported for targets which have an integer mode wide enough to hold 128 bits. Simply� A 128-bit type provided by a C compiler can be available in Perl via the Math::Int128 module. A 128-bit register can store 2 128 (over 3.40 × 10 38) different values. The range of integer values that can be stored in 128 bits depends on the integer representation used.

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.

6.9 128-bit Integers, If there is 128-bit integer type introduce in the C++ standard, what would it be called as a How can I replace/modify a particular string in a file using c++?. Answers: 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.

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.

If there is 128-bit integer type introduce in the C++ standard, what , You can write your own 128-Bit support on 32 bit CPU, the reason why it is not implemented is, that on 32 bit CPU there is no assembly opcode� The cairo graphics library has two files which implement portable 128-bit integer arithmetic: cairo-wideint-private.h, cairo-wideint.c. We include just these two in our project to get 128-bits.

There is no 128-bit integer in Visual-C++ because the Microsoft calling convention only allows returning of 2 32-bit values in the RAX:EAX pair. The presents a constant headache because when you multiply two integers together with the result is a two-word integer. Most load-and-store machines support working with two CPU word-sized integers but working with 4 requires software hack, so a 32-bit CPU cannot process 128-bit integers and 8-bit and 16-bit CPUs can't do 64-bit integers without a rather costly software hack. 64-bit CPUs can and regularly do work with 128-bit because if you multiply two 64-bit integers you get a 128-bit integer so GCC version 4.6 does support 128-bit integers. This presents a problem with writing portable code because you have to do an ugly hack where you return one 64-bit word in the return register and you pass the other in using a reference. For example, in order to print a floating-point number fast with Grisu we use 128-bit unsigned multiplication as follows:

#include <cstdint>
#if defined(_MSC_VER) && defined(_M_AMD64)
#define USING_VISUAL_CPP_X64 1
#include <intrin.h>
#include <intrin0.h>
#pragma intrinsic(_umul128)
#elif (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
#define USING_GCC 1
#if defined(__x86_64__)
#define COMPILER_SUPPORTS_128_BIT_INTEGERS 1
#endif
#endif

#if USING_VISUAL_CPP_X64
    UI8 h;
    UI8 l = _umul128(f, rhs_f, &h);
    if (l & (UI8(1) << 63))  // rounding
      h++;
    return TBinary(h, e + rhs_e + 64);
#elif USING_GCC
    UIH p = static_cast<UIH>(f) * static_cast<UIH>(rhs_f);
    UI8 h = p >> 64;
    UI8 l = static_cast<UI8>(p);
    if (l & (UI8(1) << 63))  // rounding
      h++;
    return TBinary(h, e + rhs_e + 64);
#else
    const UI8 M32 = 0xFFFFFFFF;
    const UI8 a = f >> 32;
    const UI8 b = f & M32;
    const UI8 c = rhs_f >> 32;
    const UI8 d = rhs_f & M32;
    const UI8 ac = a * c;
    const UI8 bc = b * c;
    const UI8 ad = a * d;
    const UI8 bd = b * d;
    UI8 tmp = (bd >> 32) + (ad & M32) + (bc & M32);
    tmp += 1U << 31;  /// mult_round
    return TBinary(ac + (ad >> 32) + (bc >> 32) + (tmp >> 32), e + rhs_e + 64);
#endif
  }

Why does C only have 128-bit integers on 64-bit CPUs (GCC , This implements 128-bit unsigned integer using C++14. It works on std:: uint64_t is consistently misspelt throughout the code, and may be a poor choice anyway (since an exact 64-bit type need not be provided). It's better to� __m128i is a packed vector of integers elements. SSE/AVX supports packed integer add/sub with element widths from 8b to 64b, but not 128b. Of course, boolean operations with no carry between bits (like AND/OR/XOR) Just Work.

128-bit unsigned integer, This is simple implementation of an unsigned 128 bit integer type in C++. It's meant to be used like a standard uintX_t , except with a larger bit size than those � long double: Real floating-point type, usually mapped to an extended precision floating-point number format. Actual properties unspecified. It can be either x86 extended-precision floating-point format (80 bits, but typically 96 bits or 128 bits in memory with padding bytes), the non-IEEE "double-double" (128 bits), IEEE 754 quadruple-precision floating-point format (128 bits), or the same as

calccrypto/uint128_t: C++ unsigned 128 bit integer type, As a non-standard extension, both GCC and Clang provide __uint128_t and __int128_t for emulated 128-bit integer arithmetic in C. The basic� GUID is backed by a 128 bit integer in .NET framework; though it doesn't come with any of the typical integer type methods. I've written a handler for GUID before to treat it as a 128 bit integer, but this was for a company I worked for ~8 years ago. I no longer have access to the source code.

128-bit Integer Arithmetic, SSE2 has native 128-bit math, AVX has 256-bit native integer math, and AVX- 512 has This strikes me as a little nuts for C but it definitely explains this thread. CHAR_BIT 8 Defines the number of bits in a byte. SCHAR_MIN-128 Defines the minimum value for a signed char. SCHAR_MAX +127 Defines the maximum value for a signed char. UCHAR_MAX 255 Defines the maximum value for an unsigned char. CHAR_MIN-128 Defines the minimum value for type char and its value

Comments
  • std::bitset might be useful.
  • There's libuuid for linux available BTW.
  • You're asking two different questions ... a 128-bit datatype doesn't need to be a 128-bit integer. Just use a struct consisting of two 64-bit integers, or any other combination that adds up to 128 bits.
  • @JimBalter: If a user-defined struct is a standard type, what exactly would qualify as a non-standard type?
  • Definitely an XY problem. Simply said, a "128 bit integer type" is a "128 bit type with the usual integer arithmetic operators". UUID's do not need arithmetic operators; UUID * 42 does not make sense. However, operator== is relevant.
  • only for 64-bit architectures, though. See gcc.gnu.org/onlinedocs/gcc/_005f_005fint128.html
  • 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
  • Is there a preprocessor define such as HAVE_INT_128_T or something similar we could check?
  • Upvoted because it points out an issue with the accepted answer.
  • 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).
  • Boost also has a uuid library btw.
  • @JesseGood I may use that library, but I'd like store the ids in a standard type.