用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 int
types所做的所有事情。
有一些内置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的一个图书馆。
用无限精度的整数类可能会更好,而不是一个递增大小的序列。 一些语言(如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运算是如何实现的