C++ Boost 多精度整数 uint256_t 的大小大于 32 字节

问题描述 投票:0回答:0

众所周知,C++ 内置类型 uint32_t、int32_t、uint64_t、int64_t 甚至 GCC/CLang 内置类型 __int128 和 unsigned __int128 的大小都正好等于位宽除以 8。

但是,如果您打印 Boost 的

boost::multiprecision::uint256_t
uint512_t
的 sizeof,那么 uint256_t 将得到 48 个字节而不是 32 个字节,uint512_t 将得到 80 个字节而不是 64 个字节。这两种类型的 sizeof 都比预期多了 16 个字节。 在这里查看演示.

但是

boost::multiprecision::uint128_t
的 sizeof 恰好给出了预期的 16 个字节。

看起来 Boost 的所有整数的基类

cpp_int_base
有几个字段:

data_type m_data;
unsigned  m_limbs;
bool      m_sign, m_internal, m_alias;

只有 m_data 字段包含整数位,而其他字段给了这额外的 16 个不必要的 sizeof 字节。

我的问题是否有可能以某种方式调整 Boost 多精度整数,使其仅包含数据位而没有其他内容?

换句话说,它保持符号(如果它是有符号整数)与 Intel CPU 将它保持在 int64_t 中相同,基本上最高位是符号位,其余位是编码符号补充形式。因此,Boost 整数的编码与默认的 intel uint64_t、int64_t 相同。

如果你查看模板的签名

cpp_int_base
然后你会看到:

template <unsigned MinBits, unsigned MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked,
    class Allocator, bool trivial = false>
struct cpp_int_base;

显然

trivial
似乎几乎做了必要的事情,cpp_int_base 的特化与 trivial = true 只包含两个字段:

local_limb_type m_data;
bool            m_sign;

所以只比最小可能的 sizeof 大 1 个字节。

大于 128 位的整数默认有 trivial = true,而更大的整数有 trivial = false。

但是没有办法控制

trivial
模板参数,因为如果你看一下 uint256_t 定义然后你会看到:

using uint256_t = number<cpp_int_backend<256, 256, unsigned_magnitude, unchecked, void> >  ;

并且 cpp_int_backend 在它的模板参数中没有

trivial
参数,只有 cpp_int_base 有这个微不足道的内部。但是用户无法访问 cpp_int_base,它是库的内部细节。

我也不知道 128 位整数如何恰好有 16 个字节的 sizeof,因为正如我在上面显示的那样,即使是微不足道的参数也有额外的

bool m_sign;
字段,它应该提供额外的 1 个字节(即 17 个 sizeof)。但是不知何故,128 位整数不是预期的 17 个字节,而是 16 个字节。

为什么我需要 boost 整数来拥有最少的位数。因为在我的程序中我有数百万个整数数组。除了通常的数学运算之外,我还对这些整数进行了自己的特殊数学运算。我的数学运算适用于通常的英特尔形式的整数,与表示的 int64_t 和 uint64_t 相同。但有时我需要像

+ - * / % ^ | ~
这样的常规操作,而不是实现它们我决定使用Boost多精度库。

如果 Boost 具有与 Intel 完全相同的表示,我会做

reinterpret_cast<boost::multiprecision::uint256_t &>(array[i]) *= 12345;
,没有任何中间转换或 memcpy。但是由于 Boost 有不同的格式,我必须来回编写自定义转换。

如果我这样做

^
操作例如 256 位整数需要 1-4 个 CPU 周期。而且,如果我与 Boost 格式进行转换,那么将需要 5-10 个周期,这是一个非常大的开销。

因此,我需要这种普通的 Boost 整数格式作为优化,而不是对每个操作都进行转换。

另一个不太重要的原因是,在我的模板代码中的某个地方,我需要弄清楚一些模板类型 T 的位宽是多少。如果这始终是一个普通的 Intel 格式,那么

sizeof(T) * 8
将给出数字的精确位宽。对于 Boost 格式,我需要专门化一些辅助模板结构,例如
BitWidthOf<T>::value
.

c++ boost intel biginteger boost-multiprecision
© www.soinside.com 2019 - 2024. All rights reserved.