【问题标题】:C++ 128/256-bit fixed size integer typesC++ 128/256 位固定大小整数类型
【发布时间】:2011-07-11 16:46:25
【问题描述】:

我想知道是否有其他 SO 可以推荐一个好的轻量级固定大小整数类型(128 位甚至 256 位,甚至可能是模板参数化)库。

我看过 GMP 和 co,他们非常关心,但对于我的目的来说有点太大了,我现在对简单的仅标头解决方案感兴趣。性能很重要,目标架构将是 x86 和 x86-64,也是合理的许可(也不是 GPL 或 LGPL)。

【问题讨论】:

标签: c++ types bigint


【解决方案1】:

Boost 库的数据类型是 multiprecision 库的一部分,适用于 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;

【讨论】:

    【解决方案2】:

    Xint 库目前在 review 下,成为 Boost 的一部分。尽管讨论颇有争议且审查结果尚不清楚,但该库满足您的一些要求:

    • 仅标题
    • 合理的许可

    审核期间讨论的要点之一是性能。如果被接受为官方 Boost 库,我希望性能问题能够得到及时解决。

    所以我会试一试:CodeDocumentation

    【讨论】:

    • 我刚刚阅读了您对 Seve-o 的回答的评论,您在其中阐明了您的要求。我从关于 ML 的讨论中得出的结论是,您要寻找的东西还不存在。在我看来,Xint 将被接受,并且版本 2 可能包含您在性能方面寻找的内容。它已经具备您在功能方面所需的一切。
    【解决方案3】:

    您可以使用 boost(在 1.76.0 上测试):

    #include <cstdint>
    #include <iomanip>
    #include <iostream>
    
    #include <boost/multiprecision/cpp_int.hpp>
    
    using uint512_t  = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<512,  512,  boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>, boost::multiprecision::et_off>;
    using uint1024_t = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<1024, 1024, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>, boost::multiprecision::et_off>;
    using uint2048_t = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<2048, 2048, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>, boost::multiprecision::et_off>;
    using uint4096_t = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<4096, 4096, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>, boost::multiprecision::et_off>;
    using uint8192_t = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<8192, 8192, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>, boost::multiprecision::et_off>;
    
    int main()
    {
      uint8192_t u(2U);
    
      for (int64_t i = 0; i < 4096 - 1; i++) {
          u *= 2;
      }
    
      std::cout << u << std::endl;
    } 
    

    【讨论】:

      【解决方案4】:

      某些平台上提供了一些原生 128 位类型,您往往会受到架构的限制。例如__m128 可用于 SSE2?

      http://msdn.microsoft.com/en-us/library/ayeb3ayc.aspx

      在此 ABI 中也列为 __int128

      http://www.x86-64.org/documentation/abi-0.99.pdf

      不过,uint128_tuint256_t 的首选命名可以在 SHOGUN 中找到,SHOGUN 是一个“专注于支持向量机 (SVM) 的大型机器学习工具箱”

      http://www.shogun-toolbox.org/doc/index.html

      【讨论】:

      • __m128i 是整数元素的压缩向量。 SSE/AVX 支持元素宽度从 8b 到 64b 的压缩整数加/减,但 128b。当然,位之间没有进位的布尔运算(如 AND/OR/XOR)Just Work。对于任意精度数学,SSE 不提供进位向量,因此使用整数 add / adc 通常比使用 SSE 破解更快。
      【解决方案5】:

      根据您的要求,STL 类bitset 可能适合您的需要。它响应整数类型所做的所有位操作运算符(&lt;&lt;| 等),但不幸的是不响应像 +* 这样的算术运算符。它的大小在编译时通过模板参数固定。另一个不幸的事情是,API 没有提供获取底层二进制表示的方法(例如用于流式传输),这可能会严重限制它的实用性。

      (我知道这是一个老问题,但这个答案可能对其他人有所帮助。)

      【讨论】:

        猜你喜欢
        • 2019-09-12
        • 1970-01-01
        • 1970-01-01
        • 2022-06-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-10
        相关资源
        最近更新 更多