Is there a 128 bit integer in C ++?

I need to save 128 bits of UUID length in a variable. Is there a 128-bit data type in C ++? I don't need arithmetic operations, I just want to easily store and read the value very quickly.

The new feature from C ++ 11 will also be great.

+57
c ++ performance types cross-platform uuid
Aug 26 '13 at 8:10
source share
7 answers

Support for GCC and Clang __int128

+32
Nov 20 '15 at
source share

Place an order to increase efficiency :

 #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 perform arithmetic operations with it.

+37
Aug 26 '13 at 8:17
source share

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

+35
Jan 26 '16 at 23:41
source share

Your question has two parts.

1. 128-bin integer As suggested by @PatrikBeck boost::multiprecision is a good way for really large integers.

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

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

This format is defined by Microsoft due to some internal reasons, you can even simplify it to:

 struct GUID { uint8_t Data[16]; }; 

You will get better performance with a simple structure, not an object that can handle a bunch of different things. In any case, you don’t need to do math with GUIDS, so you don’t need any fancy objects.

+8
Nov 20 '15 at 13:58
source share

There is no 128-bit integer in Visual-C ++ since the Microsoft calling convention allows only 2 32-bit values ​​to be returned in a RAX: EAX pair. Represents a constant headache, because when you multiply two integers by the result, you get an integer of two words. Most load and storage machines support working with two processor word size integers, but working with 4 requires software hacking, so a 32-bit CPU cannot handle 128-bit integers, and 8-bit and 16-bit CPUs cannot 64-bit integers without a pretty expensive software hack. 64-bit processors can and regularly work with 128-bit ones, because if you multiply two 64-bit integers, you get a 128-bit integer, so GCC 4.6 supports 128-bit integers. This creates a problem when writing portable code, because you have to make an ugly hack when you return one 64-bit word to the return register and transfer the other using the link. For example, to quickly print a floating-point number using 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 } 
+2
Jul 29 '19 at 6:19 06:19
source share

use the TBigInteger pattern and set any bit range in the pattern array, for example, TBigInt <128, true> for a 128-bit signed integer or TBigInt <128, false> for a 128-bit unsigned integer. Hope this helps, maybe a late answer, and someone already found this method.

0
Dec 15 '18 at 21:30
source share

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

0
May 17 '19 at 16:30
source share



All Articles