在 C++ 中表示 128 位数字的最佳方式是什么? 它的行为应该尽可能接近内置数字类型(即支持所有算术运算符等)。
我正在考虑构建一个具有 2 个 64 位或 4 个 32 位数字的类。 或者可能只是创建一个 128 位内存块并自己完成所有事情。
是否有一些更简单/更标准的方法,或者我自己实现时不太可能搞砸的方法? :)
如果可以扩展到 256 位、512 位等,那就太好了……
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).
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.
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...
发布评论
评论(9)
编辑:当我第一次写这个
boost::multi precision::uint128_t
还没有出现。 由于历史原因保留这个答案。我之前做过一个uint128类,你可以在以下位置查看: http://www.codef00 .com/code/uint128.h。
它依赖于 boost 自动提供数学运算符的所有变体,因此它应该支持本机
unsigned int
类型所做的一切。内置类型有一些小的扩展,例如使用如下字符串初始化它:
有一个方便的宏,其工作方式与 C99 中的宏类似,您可以像这样使用:
EDIT: when I first wrote this
boost::multiprecision::uint128_t
wasn't a thing yet. Keeping this answer for historical reasons.I've made a uint128 class before, you can check it out at: 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.There are some minor extensions to built in types such as initializing it with a string like this:
There is a convenience macro which works similary to the ones in C99 which you can use like this:
这是一种特殊情况,特别是因为您没有指定您要寻找的平台,但是使用 GCC,您可以使用所谓的模式(TI)来获取(合成的)128 位操作,例如实例:
不过,这只适用于 64 位处理器。
不管怎样,您正在寻找多精度算术来解决这个问题。 mode(TI) 将导致编译器为您生成操作,否则必须显式编写它们。
可以使用通用的bigint包; 我所知道的 C++ 包括数论包 LiDIA 和 < a href="http://www.shoup.net/ntl/" rel="noreferrer">NTL,以及 Crypto++ 和 Botan)。 当然还有 GnuMP,它是规范的 C MPI 库(它也有一个 C++ 包装器,尽管我上次查看时似乎记录得很差)。 所有这些都设计得很快,但也可能针对更大(1000 位以上)的数字进行调整,因此在 128 位时,您可能会处理大量开销。 (另一方面,你没有说这是否重要)。 所有这些(与 bigint-cpp 包不同,它是 GPL,不是 BSD 就是 LGPL) - 不确定它是否重要 - 但它可能很重要。
您还可以编写自定义 uint128_t 类型; 通常,这样的类将实现与常规 MPI 类几乎相同的算法,只是硬编码为只有 2 或 4 个元素。 如果您好奇如何实现此类算法,一个很好的参考是 第 14 章 。
当然,如果您实际上不需要所有算术运算(特别是除法和取模,相当棘手),那么手动执行此操作会更容易 例如,如果您只需要跟踪一个假设可能溢出 64 位的计数器,您可以将其表示为一对 64 位长整型并手动进行进位:
这当然会简单得多比一般 MPI 包或自定义 uint128_t 类处理。
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:
This only works on 64-bit processors, though.
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.
You can use a general bigint package; ones in C++ I know of include the number theory packages LiDIA and 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.
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
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:
Which of course is going to be a lot simpler to deal with than a general MPI package or a custom uint128_t class.
Boost 的数据类型为
多精度
库,适用于 128 到 1024 位的类型。Boost has data types in
multiprecision
library for types ranging from 128 to 1024 bits.GCC 支持支持 128 位整数类型的处理器。 您可以使用以下方式访问它:
02020-02-10 更新:根据 这个:GCC、Clang 和 Intel ICC 都支持内置的 __int128 类型。
GCC supports a 128-bit integer type for processors which support it. You can access it using:
02020-02-10 Update: according to this: GCC, Clang, and Intel ICC all support a built-in __int128 type.
您可能想尝试 GMP
You may want to try GMP
这是我在谷歌上找到的一个图书馆。
http://sourceforge.net/projects/cpp-bigint/
Here is a library I found on google.
http://sourceforge.net/projects/cpp-bigint/
您可能会更好地使用无限精度的整数类,而不是大小不断增加的序列。 有些语言(例如 Common Lisp 和 IIRC Python)本身就有它们。 我暂时不确定 C++ 有什么可用的; 最后我看了看没有 Boost 版本。
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.
cairo 图形库有两个实现可移植 128 位整数运算的文件:cairo-wideint-private.h、cairo-wideint.c。 我们在项目中仅包含这两个以获得 128 位。
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.
在 Visual Studio C++ 中,有一个类型 FLOAT128 用于表示 128 位整数。 它的实现方式是:
所以我不确定为其实现了哪些数学运算
In Visual Studio C++ there is a type FLOAT128 that is used to represent 128-bit integers. It is implemented as:
so I'm not sure about what math operations are implemented for it