【问题标题】:GMP - Store 64 bit interger in mpz_t/mpz_class and get 64 bit integers backGMP - 在 mpz_t/mpz_class 中存储 64 位整数并取回 64 位整数
【发布时间】:2018-07-30 20:14:52
【问题描述】:

我想将 64 位整数中的值分配给 mpz_class/mpz_t 变量,然后再取回 64 位整数。但是 GMP 只为 32 位和更低的整数提供此功能。

那么我如何将 64 位整数转换为 mpz_class/mpz_t 变量,反之亦然。 (有符号和无符号整数都需要它)

【问题讨论】:

  • 也许可以使用mpz_importmpz_export 来完成?
  • 请原谅我的愚蠢问题,但是ropop 是什么?这些中的哪一个获得了价值?而且只有一个值,字节序应该无关紧要,对吧?这似乎适用于无符号整数,但有符号整数呢?编辑:我现在了解ropop 之间的区别
  • 我会为你创建一个答案:)
  • @BrainStone Endianess 很重要,因为您的值是 8 个字节,只需选择 0 表示“本机”字节序
  • @john 你是对的。我的意思是订单(参数)。如果我没记错的话,那真的不重要。

标签: c++ integer 64-bit assign


【解决方案1】:

这可以通过mpz_import() and mpz_export() 函数来实现。
代码示例(在 LP64 数据模型上测试):

using Type = int64_t;

// We start with some 64bit integer
const Type builtIn64 = std::numeric_limits<Type>::min();
std::cout << builtIn64 << '\n';

// Import the integer into the mpz_class
mpz_t mpzNum;
mpz_init(mpzNum);
mpz_import(mpzNum, 1, 1, sizeof(Type), 0, 0, &builtIn64);
if (builtIn64 < 0) {
    mpz_neg(mpzNum, mpzNum);
}
std::cout << mpz_class(mpzNum) << '\n';

// Export the mpz_t value to a buffer allocated by the function and given
// the word size, get also the number of words required to hold the value
const size_t wordSize = sizeof(Type);
size_t wordCount = 0;
void* outRaw = mpz_export(nullptr, &wordCount, 1, wordSize, 0, 0, mpzNum);

// Make sure that our integer type can still hold the value
if (wordCount == 1) {
    const Type out = *static_cast<Type*>(outRaw);
    std::cout << out << '\n';
}

// Free the allocated memory by mpz_export
void (*freeFunction)(void*, size_t);
mp_get_memory_functions(nullptr, nullptr, &freeFunction);
freeFunction(outRaw, wordCount * wordSize);

// Don't forget to free the allocated memory
mpz_clear(mpzNum);

LIVE DEMO

【讨论】:

  • 既然mpz_export在这种情况下返回一个uint64_t数组,我们不能只检查wordCount,如果它是1,就只需要out = allocated[0]; delete[] allocated;吗?
  • @BrainStone 你是绝对正确的,我已经编辑了答案。但是,请记住,您不能使用delete[] 来释放由mpz_export 分配的内存,因为它肯定不是使用new 来分配内存。您不能将newfree 以及mallocdelete 混合使用。使用 API 获取 free() 函数要安全得多。
  • @BrainStone 我仍在寻找一种方法来告诉mpz_t 这是一个有符号值。当您将 int64_t 转换为 mpz_t 并返回时,它可以工作,但 mpz_t 本身似乎无法处理已签名的值。
  • 谢谢!同样来自我在这里读到的内容:stackoverflow.com/a/5013661/1996022 最好在这里使用static_cast,因为我们知道void* 实际上是uint64_t*(或者至少单词大小相同)
  • 是的,你是对的,wordCount == 1 条件使它成为可能:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-14
  • 2020-01-11
  • 2019-08-17
相关资源
最近更新 更多