C + + 中有128位整数吗?

我需要在一个变量中存储一个128位长的 UUID。C + + 中有128位的数据类型吗?我不需要算术运算,我只是想方便地存储和读取值非常快。

C + + 11的一个新特性也可以。

107114 次浏览

结帐 推广计划的实施:

#include <boost/multiprecision/cpp_int.hpp>


using namespace boost::multiprecision;


int128_t v = 1;

这比字符串和数组要好,特别是如果您需要使用它进行算术运算的话。

你的问题分为两部分。

1. 128-bit整数。正如@PatrikBeck 建议的那样,boost::multiprecision对于真正的大整数来说是一种很好的方法。

2.变量来存储 UUID/GUID/CLSID或任何你称之为它的东西。在这种情况下,boost::multiprecision不是一个好主意。你需要的 GUID 结构就是为此而设计的。随着跨平台标记的添加,您可以简单地将该结构复制到代码中,并使其类似于:

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

由于一些内在原因,Microsoft 定义了这种格式,您甚至可以将其简化为:

struct GUID
{
uint8_t Data[16];
};

使用简单的结构比使用能够处理大量不同内容的对象能够获得更好的性能。无论如何,您不需要使用 GUID 做数学计算,所以您不需要任何奇特的对象。

GCC 和 Clang 支持 __int128

虽然 GCC 确实提供了 __int128,但它只支持目标(处理器) ,这些处理器的整数模式足以容纳128位。在给定的系统上,sizeof () intmax_tuintmax_t确定编译器和平台支持的最大值。

使用 TBigInteger模板并在模板数组中设置任何位范围,如将 TBigInt<128,true>设置为有符号的128位整数,或将 TBigInt<128,false>设置为无符号的128位整数。

希望这可以帮助也许一个后来的答复和其他人已经发现了这个方法。

TBigInt 是由 虚幻引擎定义的结构,它提供了一个多位整数覆盖。

基本用法(据我所知) :

#include <Math/BigInt.h>


void foo() {
TBigInt<128, true> signed128bInt = 0;
TBigInt<128, false> unsigned128bInt = 0;
}

我建议使用 std::bitset<128>(你总是可以做类似于 using UUID = std::bitset<128>;的事情)。它可能与其他答案中提出的自定义结构具有类似的内存布局,但是您不需要定义自己的比较运算符、散列等。

Visual-C + + 中没有128位整数,因为 Microsoft 调用约定只允许返回 RAX: EAX 对中的2个32位值。当你将两个整数相乘,结果是一个两字整数时,它会给你带来持续的麻烦。大多数加载和存储机器支持处理两个 CPU 字大小的整数,但处理4需要软件黑客技术,所以32位 CPU 不能处理128位整数,8位和16位 CPU 不能处理64位整数,除非有一个相当昂贵的软件黑客技术。64位 CPU 可以并且经常处理128位整数,因为如果你将两个64位整数相乘得到一个128位整数,所以 GCC 版本4.6确实支持128位整数。这给编写可移植代码带来了一个问题,因为您必须进行一个丑陋的黑客操作,即在返回寄存器中返回一个64位字,并使用引用传递另一个字。例如,为了用 格里苏快速打印浮点数,我们使用128位无符号乘法,如下所示:

#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
}