在C++中表示128位数的最佳方法是什么?它应该尽可能地与内置数值类型一致(即支持所有算术运算符等).
我正在考虑构建一个具有2个64位或4个32位数的类.或者可能只是创建一个128位的内存块并自己完成所有操作.
是否有一些更容易/更标准的方式,或者我自己实施它时不太可能搞砸的东西?:)
如果它可以扩展到256位,512位等等也会很好...
Eva*_*ran 66
编辑:我第一次写这篇文章时还boost::multiprecision::uint128_t
不是.保持这个答案的历史原因.
我之前做了一个uint128课程,你可以在http://www.codef00.com/code/uint128.h查看.
它依赖于boost来自动提供数学运算符的所有变体,因此它应该支持本机unsigned int
类型所做的一切.
内置类型有一些小的扩展,例如使用如下字符串初始化它:
uint128_t x("12345678901234567890");
Run Code Online (Sandbox Code Playgroud)
有一个方便的宏,它的工作原理类似于C99,你可以这样使用:
uint128_t x = U128_C(12345678901234567890);
Run Code Online (Sandbox Code Playgroud)
Jac*_*oyd 20
这是一种特殊情况有点,特别是因为你没有指定你要找什么平台上,但与海湾合作委员会,你可以使用所谓模式(TI)得到(合成)的128位操作,例如:
typedef unsigned int uint128_t __attribute__((mode(TI)));
uint64_t x = 0xABCDEF01234568;
uint64_t y = ~x;
uint128_t result = ((uint128_t) x * y);
printf("%016llX * %016llX -> ", x, y);
uint64_t r1 = (result >> 64);
uint64_t r2 = result;
printf("%016llX %016llX\n", r1, r2);
Run Code Online (Sandbox Code Playgroud)
但这仅适用于64位处理器.
无论如何,您正在寻找多种精确算法来解决这个问题.mode(TI)将使编译器为您生成操作,否则必须明确写入.
你可以使用一般的bigint包; 在C++中,我知道包括数论理论包LiDIA和NTL,以及用于Crypto ++和Botan中的加密代码的bigint包.当然还有GnuMP,这是规范的C MPI库(它确实有一个C++包装器,虽然上次看到它时看起来很难记录).所有这些都设计得很快,但也可能针对更大(1000+位)的数字进行调整,因此在128位时你可能会遇到很多开销.(另一方面,你不说是否重要).所有这些(与bigint-cpp包不同,它是GPL,是BSD或LGPL) - 不确定它是否重要 - 但它可能很重要.
你也可以写一个自定义的uint128_t类型; 通常这样的类会实现与常规MPI类相同的算法,只需硬编码只有2或4个元素.如果您对如何实现此类算法感到好奇,那么很好的参考是"应用密码学手册"的第14章
当然,如果你实际上并不需要所有算术运算(除法和模数,特别是相当棘手),那么手工操作会更容易.例如,如果你只需要跟踪一个可能假设溢出64位的计数器,你可以将它表示为一对64位长的long并手动执行:
unsigned long long ctrs[2] = { 0 };
void increment() {
++ctrs[0];
if(!ctrs[0]) // overflow
++ctrs[1];
}
Run Code Online (Sandbox Code Playgroud)
当然,与一般的MPI包或自定义的uint128_t类相比,处理起来要简单得多.
Boost在multiprecision
库中具有数据类型,类型范围从128到1024位.
#include <boost/multiprecision/cpp_int.hpp>
using namespace boost::multiprecision;
int128_t mySignedInt128 = -1;
uint128_t myUnsignedInt128 = 2;
int256_t mySignedInt256 = -3;
uint256_t myUnsignedInt256 = 4;
int512_t mySignedInt512 = -5;
uint512_t myUnsignedInt512 = 6;
int1024_t mySignedInt1024 = -7;
uint1024_t myUnsignedInt1024 = 8;
Run Code Online (Sandbox Code Playgroud)
对于支持它的处理器,GCC支持128 位整数类型。您可以使用以下方式访问它:
__int128 a;
unsigned __int128 b;
Run Code Online (Sandbox Code Playgroud)
02020-02-10 更新:根据这个:GCC、Clang 和 Intel ICC 都支持内置的 __int128 类型。