用C ++表示128位数字

用C ++表示128位数字的最好方法是什么? 它应该尽可能地和内置的数字types(即支持所有的算术运算符等)保持一致。

我正在考虑build立一个具有2个64位或4个32位数的类。 或者可能只是创build一个128位的内存块,自己做一切。

有一些更简单/更标准的方法,或者我自己实现时不太可能搞砸的东西? 🙂

如果它可以扩展到256位,512位等,也是很好的。

看看已经开发的其他库。 很多人都想在你面前这样做。 :d

尝试bigint C ++

编辑:当我第一次写这个boost::multiprecision::uint128_t是不是一件事。 由于历史原因保持这个答案。


我已经做了一个uint128类,你可以看看: http : //www.codef00.com/code/uint128.h 。

它依赖boost来自动提供math运算符的所有变体,所以它应该支持本地unsigned inttypes所做的所有事情。

有一些内置types的小扩展,比如像这样用一个string初始化它:

 uint128_t x("12345678901234567890"); 

有一个方便的macros,它可以像C99一样工作,你可以这样使用:

 uint128_t x = U128_C(12345678901234567890); 

这是一个特殊情况,特别是因为您没有指定要查找的平台,但是使用GCC,您可以使用所谓的模式(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); 

但是,这只适用于64位处理器。

无论如何,你正在寻找多个精度algorithm来解决这个问题。 模式(TI)将使编译器为您生成操作,否则必须明确写入。

你可以使用一般的bigint包装; 在C ++中我知道包括数字理论软件包LiDIA和NTL ,以及用于Crypto ++和Botan中的encryption代码的bigint软件包)。 另外当然还有GnuMP ,它是规范的C MPI库(它也有一个C ++包装器,尽pipe上次我看它的时候看起来很差)。 所有这些都被devise得很快,但也可能被调整为较大(1000+位)的数字,所以在128位,你可能会处理大量的开销。 (另一方面,你不说如果重要的话)。 所有这些(不像bigint-cpp软件包,这是GPL,不是BSD或者LGPL) – 不确定是否重要 – 但是这可能很重要。

你也可以写一个自定义的uint128_ttypes的types; 通常这样的类将实现与常规MPI类相同的algorithm,只是硬编码为只有2或4个元素。 如果你对如何实现这样的algorithm感到好奇,那么应该参考一下应用密码学手册第14章

当然,如果实际上并不需要所有的算术运算(尤其是分数和模数,相当棘手),那么手工操作就更容易。 例如,如果您只需要跟踪一个可能假设溢出64位的计数器,则可以将其表示为一对64位长的长整数,然后手动进行:

 unsigned long long ctrs[2] = { 0 }; void increment() { ++ctrs[0]; if(!ctrs[0]) // overflow ++ctrs[1]; } 

当然比一般的MPI包或者一个自定义的uint128_t类要简单得多。

Boost在多multiprecision库中有128到1024位的数据types。

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

不要重蹈覆辙 – 我很积极,其他人已经解决了这个问题,尽pipe我不能说出任何解决scheme。 GMP可以肯定地解决你的问题,虽然它对于固定大小的整数是过度的,并且使用起来也很麻烦(它是一个C库,而不是C ++)。

你可能想尝试GMP

GCC 支持 128位整数types的处理器支持它。 您可以使用以下方式访问它

 __int128 a; unsigned __int128 b; 

这是我在google上find的一个图书馆。

http://sourceforge.net/projects/cpp-bigint/

用无限精度的整数类可能会更好,而不是一个递增大小的序列。 一些语言(如Common Lisp和IIRC Python)本来就有它们。 我不确定C ++有什么可用的; 最后我看了没有一个升压版本。

开罗graphics库有两个文件实现可移植的128位整数算术:cairo-wideint-private.h,cairo-wideint.c。 我们在这个项目中只包含了这两个来获得128位。

在Visual Studio C ++中,有一个用于表示128位整数的FLOAT128types。 它被实现为:

 #if defined(_M_IA64) && !defined(MIDL_PASS) __declspec(align(16)) #endif typedef struct _FLOAT128 { __int64 LowPart; __int64 HighPart; } FLOAT128; 

所以我不确定math运算是如何实现的