gpt4 book ai didi

gmp - GMP/MPFR 肢体应如何解释?

转载 作者:行者123 更新时间:2023-12-02 18:57:20 27 4
gpt4 key购买 nike

任意精度库 GMP 和 MPFR 使用机器字大小整数的堆分配数组来存储构成高精度数字/尾数的肢体。

应该如何解释这个肢体数组以恢复任意精度整数?换句话说:对于 N 个肢体,每个肢体持有 B 位,我应该如何解释它们以恢复 N*B 位数字?

肢体大小真的会影响内存中的表示(见下文)吗?如果是这样,其背后的理由是什么?


背景:

我编写了一个小程序来查看表示的内部,但我对所看到的感到困惑。肢体似乎按最高有效数字顺序排序,而肢体本身则采用 native 最低有效数字格式。当使用 32 位字和固定为 128 位的精度表示 64 位字 0xAAAABBBBCCCCDDDD 时,我看到:

% c++ limbs.cpp -lgmp -lmpfr -o limbs && ./limbs
ccccdddd|aaaabbbb|00000000|00000000
00000000|00000000|ccccdddd|aaaabbbb

这似乎意味着内存中的表示不能作为位字符串读回以恢复任意精度数(例如,如果将其加载到支持的机器上的寄存器中) N*B 大小的单词)。此外,这似乎也表明肢体大小改变了表示形式,因此在不知道使用哪个肢体大小来序列化数字的情况下,我将无法反序列化数字。

这是我的测试程序(使用 32 位肢体和 __GMP_SHORT_LIMB 宏):

#define __GMP_SHORT_LIMB
#include <gmp.h>
#include <mpfr.h>

#include <iomanip>
#include <iostream>

constexpr int PRECISION = 128;

void PrintLimbs(mp_limb_t const *const limbs) {
std::cout << std::hex;
constexpr int NUM_LIMBS = PRECISION / (8 * sizeof(mp_limb_t));
for (int i = 0; i < NUM_LIMBS; ++i) {
std::cout << std::setfill('0') << std::setw(2 * sizeof(mp_limb_t)) << limbs[i];
if (i < NUM_LIMBS - 1) {
std::cout << "|";
}
}
std::cout << "\n";
}

int main() {
{ // GMP
mpz_t num;
mpz_init2(num, PRECISION);
mpz_set_ui(num, 0xAAAABBBBCCCCDDDD);
PrintLimbs(num->_mp_d);
mpz_clear(num);
}
{ // MPFR
mpfr_t num;
mpfr_init2(num, PRECISION);
mpfr_set_ui(num, 0xAAAABBBBCCCCDDDD, MPFR_RNDN);
PrintLimbs(num->_mpfr_d);
mpfr_clear(num);
}
return 0;
}

最佳答案

对于字节表示来说重要的三件事:

  • 肢体尺寸取决于您的机器和所选的 ABI。实际大小还受到可选存在的指甲的影响(这是一个实验特征,因此四肢不太可能有指甲)。 MPFR 不支持指甲的存在。
  • 内存中的肢体表示遵循机器的字节顺序。
  • 肢体首先存储最低有效肢体(也称为小端)。

请注意,从最后两点来看,在同一台大端机器上,数组的字节表示将取决于肢体大小。

关于肢体阵列的大小,取决于类型。比如GMP的mpn层,完全由用户自己处理。

对于 MPFR,大小是根据 mpfr_t 对象的精度推导出来的;如果精度不是肢体位大小的倍数,则尾随位始终设置为 0。另请注意,可能会分配比实际使用的内存更多的内存,并且不得将其与数组的大小混淆;您可以忽略这个事实,因为未使用的数据始终位于实际的肢体数组之后。

编辑关于基本原理:操作肢体而不是字节是出于速度原因。然后我认为选择小端法来表示肢体数组有两个原因。首先,它使基本运算(加法、减法、乘法)更容易实现并且可能更快。其次,实现模 2^K 算术要好得多,特别是当 K 可能发生变化时。

关于gmp - GMP/MPFR 肢体应如何解释?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66031553/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com