77

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

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

4

7 回答 7

71

尽管 GCC 确实提供__int128了 ,但它仅支持具有足够宽以容纳 128 位的整数模式的目标(处理器)。在给定的系统上,sizeof()intmax_tuintmax_t确定编译器和平台支持的最大值。

于 2016-01-26T23:41:30.847 回答
46

GCC 和 Clang 支持__int128

于 2015-11-20T14:07:45.403 回答
44

Checkout boost的实现

#include <boost/multiprecision/cpp_int.hpp>

using namespace boost::multiprecision;

int128_t v = 1;

这比字符串和数组要好,尤其是当您需要用它进行算术运算时。

于 2013-08-26T08:17:42.857 回答
12

你的问题有两个部分。

1.128-bit整数。正如@PatrikBeck 所建议的boost::multiprecision那样,对于真正的大整数来说是个好方法。

2.Variable 来存储UUID//GUIDCLSID任何你称之为的东西。在这种情况下boost::multiprecision不是一个好主意。您需要为此目的设计的GUID 结构。随着跨平台标签的添加,您可以简单地将该结构复制到您的代码中并使其如下所示:

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

这种格式是微软定义的,因为一些内在的原因,你甚至可以将其简化为:

struct GUID
{
    uint8_t Data[16];
};

您将获得更好的性能,具有简单的结构而不是可以处理一堆不同东西的对象。无论如何,您不需要使用 GUIDS 进行数学运算,因此您不需要任何花哨的对象。

于 2015-11-20T13:58:02.037 回答
6

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

于 2019-05-17T16:30:08.333 回答
4

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 位整数。这给编写可移植代码带来了问题,因为您必须做一个丑陋的 hack,在返回寄存器中返回一个 64 位字,然后使用引用传递另一个字。例如,为了快速打印浮点数Grisu我们使用 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
  }
于 2019-07-29T06:19:53.710 回答
1

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

希望这可能有助于迟到的回复,并且其他人已经找到了这种方法。

TBigInt 是由Unreal Engine定义的结构。它提供了一个多位整数覆盖。

基本用法(据我所知):

#include <Math/BigInt.h>

void foo() {
    TBigInt<128, true> signed128bInt = 0;
    TBigInt<128, false> unsigned128bInt = 0;
}
于 2018-12-15T21:30:06.453 回答