在 C++ 中表示 128 位数字
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1188939/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Representing 128-bit numbers in C++
提问by David Coufal
What's the best way to represent a 128-bit number in C++? It should behave as closely to the built-in numeric types as possible (i.e. support all the arithmetic operators, etc).
在 C++ 中表示 128 位数字的最佳方式是什么?它应该尽可能接近内置数字类型(即支持所有算术运算符等)。
I was thinking of building a class that had 2 64 bit or 4 32 bit numbers. Or possibly just creating a 128 bit block of memory and doing everything myself.
我正在考虑构建一个具有 2 个 64 位或 4 个 32 位数字的类。或者可能只是创建一个 128 位的内存块并自己做所有事情。
Is there some easier/more standard way, or something that I'm less likely to screw up when implementing it myself? :)
是否有一些更简单/更标准的方法,或者我自己实施时不太可能搞砸的东西?:)
It would also be nice if it could be extended to 256-bit, 512-bit, etc...
如果它可以扩展到 256 位、512 位等也很好……
采纳答案by Gordon Gustafson
Look into other libraries that have been developed. Lots of people have wanted to do this before you. :D
查看已开发的其他库。在你之前,很多人都想这样做。:D
Try bigint C++
回答by Evan Teran
EDIT:when I first wrote this boost::multiprecision::uint128_t
wasn't a thing yet. Keeping this answer for historical reasons.
编辑:当我第一次写这boost::multiprecision::uint128_t
还不是一件事。由于历史原因保留此答案。
I've made a uint128 class before, you can check it out at: http://www.codef00.com/code/uint128.h.
我之前做过一个 uint128 类,你可以在:http: //www.codef00.com/code/uint128.h 查看。
It is dependent on boost for automatically providing all of the variants of the math operators, so it should support everything a native unsigned int
type does.
它依赖于 boost 自动提供数学运算符的所有变体,因此它应该支持本机unsigned int
类型所做的一切。
There are some minor extensions to built in types such as initializing it with a string like this:
内置类型有一些小的扩展,例如用这样的字符串初始化它:
uint128_t x("12345678901234567890");
There is a convenience macro which works similary to the ones in C99 which you can use like this:
有一个方便的宏,它的工作原理类似于 C99 中的宏,您可以像这样使用:
uint128_t x = U128_C(12345678901234567890);
回答by Hyman Lloyd
This is somewhat of a special case, especially since you didn't specify what platform(s) you're looking for, but with GCC you can use what is called mode(TI) to get (synthesized) 128-bit operations, for instance:
这是一种特殊情况,特别是因为您没有指定要查找的平台,但是使用 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);
This only works on 64-bit processors, though.
不过,这只适用于 64 位处理器。
One way or another, you're looking at multiple precision arithmetic to solve this. mode(TI) will cause the compiler to generate the operations for you, otherwise they have to be written explicitly.
以一种或另一种方式,您正在寻找多精度算术来解决这个问题。mode(TI) 将使编译器为您生成操作,否则必须显式编写它们。
You can use a general bigint package; ones in C++ I know of include the number theory packages LiDIAand NTL, and the bigint packages used for cryptographic code in Crypto++and Botan). Plus of course there is GnuMP, which is the canonical C MPI library (and it does have a C++ wrapper as well, though it seemed poorly documented last time I looked at it). All of these are designed to be fast, but are also probably tuned for larger (1000+ bit) numbers, so at 128 bits you may be dealing with a lot of overhead. (On the other hand you don't say if that matters or not). And all of them (unlike the bigint-cpp package, which is GPL, are either BSD or LGPL) - not sure if it matters - but it might matter a lot.
您可以使用通用的 bigint 包;我所知道的 C++ 中的那些包括数论包LiDIA和NTL,以及用于Crypto++和Botan 中的密码代码的 bigint 包)。另外当然还有GnuMP,它是规范的 C MPI 库(它也有一个 C++ 包装器,尽管上次我看它时似乎没有很好的记录)。所有这些都设计得很快,但也可能针对更大的(1000+ 位)数字进行了调整,因此在 128 位时,您可能会处理大量开销。(另一方面,您不会说这是否重要)。所有这些(与 bigint-cpp 包不同,它是 GPL,不是 BSD 就是 LGPL)——不确定它是否重要——但它可能很重要。
You could also write a custom uint128_t kind of type; typically such a class would implement much the same algorithms as a regular MPI class, just hardcoded to have only 2 or 4 elements. If you are curious how to implement such algorithms, a good reference is Chapter 14 of the Handbook of Applied Cryptography
您还可以编写自定义 uint128_t 类型;通常,这样的类将实现与常规 MPI 类大致相同的算法,只是硬编码为只有 2 或 4 个元素。如果你很好奇如何实现这样的算法,一个很好的参考是应用密码学手册的第 14 章
Of course doing this by hand is easier if you don't actually need all the arithmetic operations (division and modulo, in particular, are rather tricky). For instance, if you just need to keep track of a counter which might hypothetically overflow 64 bits, you could just represented it as a pair of 64 bit long longs and do the carry by hand:
当然,如果您实际上不需要所有算术运算(特别是除法和取模相当棘手),那么手动执行此操作会更容易。例如,如果您只需要跟踪一个可能假设溢出 64 位的计数器,您可以将其表示为一对 64 位 long long 并手动进行进位:
unsigned long long ctrs[2] = { 0 };
void increment() {
++ctrs[0];
if(!ctrs[0]) // overflow
++ctrs[1];
}
Which of course is going to be a lot simpler to deal with than a general MPI package or a custom uint128_t class.
这当然比通用 MPI 包或自定义 uint128_t 类更容易处理。
回答by Tuxdude
Boost has data types in multiprecision
library for types ranging from 128 to 1024 bits.
Boostmultiprecision
库中的数据类型范围从 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;
回答by Richard
GCC supportsa 128-bit integer type for processors which support it. You can access it using:
对于支持它的处理器,GCC支持128 位整数类型。您可以使用以下方式访问它:
__int128 a;
unsigned __int128 b;
02020-02-10 Update: according to this: GCC, Clang, and Intel ICC all support a built-in __int128 type.
02020-02-10 更新:根据这个:GCC、Clang 和 Intel ICC 都支持内置的 __int128 类型。
回答by Adam Rosenfield
Don't reinvent the wheel -- I'm positive other people have already solved this problem, although I can't name any solutions off the top of my head. GMPcan surely solve your problem, although it's overkill for fixed-size integers, and it's also a little cumbersome to use (it's a C library, not C++).
不要重新发明轮子——我很确定其他人已经解决了这个问题,尽管我无法说出任何解决方案。 GMP肯定可以解决您的问题,尽管它对于固定大小的整数来说有点矫枉过正,而且使用起来也有点麻烦(它是一个 C 库,而不是 C++)。
回答by Daniel A. White
回答by David Thornley
You might be better off with an infinite-precision integer class, rather than a sequence of increasing size. Some languages (like Common Lisp and IIRC Python) have them natively. I'm not sure offhand what's available for C++; last I looked there wasn't a Boost version.
使用无限精度整数类可能会更好,而不是大小增加的序列。一些语言(如 Common Lisp 和 IIRC Python)本身就有它们。我不确定 C++ 有什么可用的;最后我看没有Boost版本。
回答by pdbj
The cairo graphics library has two files which implement portable 128-bit integer arithmetic: cairo-wideint-private.h, cairo-wideint.c. We include just these two in our project to get 128-bits.
cairo 图形库有两个实现可移植 128 位整数算法的文件:cairo-wideint-private.h、cairo-wideint.c。我们在我们的项目中只包含这两个以获得 128 位。