3 回答
TA贡献1875条经验 获得超3个赞
这在某种程度上是一种特殊情况,特别是因为您没有指定要查找的平台,但是在GCC中,您可以使用所谓的mode(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位处理器。
一种或另一种方式,您正在寻找多重精度算法来解决此问题。mode(TI)将使编译器为您生成操作,否则必须显式编写它们。
您可以使用通用的bigint包;我知道的C ++中包括数字理论软件包LiDIA和NTL,以及用于Crypto ++和Botan中的加密代码的bigint软件包)。加上当然还有GnuMP,它是规范的C MPI库(它也具有C ++包装器,尽管上次查看时似乎文献记载很少)。所有这些设计的速度都很快,但也可能针对更大的数字(1000+位)进行了调整,因此在128位时,您可能要处理很多开销。(另一方面,您不会说这是否重要)。而且所有这些(与bigint-cpp软件包(即GPL一样,不是BSD还是LGPL))-不确定是否重要-但这可能很重要。
您也可以编写一个自定义的uint128_t类型的类型。通常,这种类将实现与常规MPI类几乎相同的算法,只是将其硬编码为仅包含2个或4个元素。如果您对如何实现这种算法感到好奇,可以参考《应用密码学手册》第14章。
当然,如果您实际上不需要所有的算术运算(尤其是除法和模运算,则相当棘手),则手动进行操作会更容易。例如,如果您只需要跟踪一个假设可能溢出64位的计数器,则可以将其表示为一对64位长的long,然后手动进行进位:
unsigned long long ctrs[2] = { 0 };
void increment() {
++ctrs[0];
if(!ctrs[0]) // overflow
++ctrs[1];
}
当然,与一般的MPI包或自定义的uint128_t类相比,处理哪个当然要简单得多。
- 3 回答
- 0 关注
- 1014 浏览
添加回答
举报