以下代码在 Linux/Debian (g++ 10.2) 下工作正常(编译,断言语句给出 true),但拒绝在 Windows (mingw64 g++ 12.2.0) 下工作。它基本上只是应该将 gmp 中的 UINT64_MAX
分配给 mpf_class
库,但似乎 gmp 的 mpf_class 没有为 uint64_t 定义任何构造函数和运算符,它在我试图在这里使用的 Windows 环境中是 unsigned long long int 。我敢打赌,我现在还没有看到一个简单的解决方法,因为现在是周五,而且很晚,对吗?
#include <gmpxx.h> // link with gmp + gmpxx
#include <string>
/// Helper to convert mpf_class to std::string
[[nodiscard]] inline std::string mpf_class_to_str(const mpf_class& num) {
mp_exp_t exponent(1);
return num.get_str(exponent, 10);
}
int main() {
mpf_class y = UINT64_MAX; // defined in my mingw64 as 0xffffffffffffffffULL
// ^
// | adding no cast -> compile error
// adding (unsigned int) cast -> compiles, but assertion below false
// adding (uint64_t) cast -> compile error
y *= UINT64_MAX; // UINT64_MAX²
assert(mpf_class_to_str(y) == "340282366920938463426481119284349108225");
}
g++ 给我的编译错误是:
error: conversion from 'long long unsigned int' to 'mpf_class' is ambiguous
31 | mpf_class y = UINT64_MAX;
| ^~~~~~~~~~
然后它列出了所有候选者,它们基本上是(取自gmpxx.h
而不是错误日志):
#define __GMPXX_DEFINE_ARITHMETIC_CONSTRUCTORS \
__gmp_expr(signed char c) { init_si(c); } \
__gmp_expr(unsigned char c) { init_ui(c); } \
__gmp_expr(signed int i) { init_si(i); } \
__gmp_expr(unsigned int i) { init_ui(i); } \
__gmp_expr(signed short int s) { init_si(s); } \
__gmp_expr(unsigned short int s) { init_ui(s); } \
__gmp_expr(signed long int l) { init_si(l); } \
__gmp_expr(unsigned long int l) { init_ui(l); } \
__gmp_expr(float f) { init_d(f); } \
__gmp_expr(double d) { init_d(d); }
如果我操作该 header ,添加行 __gmp_expr(unsigned long long int l) { init_ui(l); }
一切都很好,只是这个修复对于我来说也太肮脏了。
最佳答案
mpz_class
无法从(无符号)long long
构造。 documentation 中也有说明。 .
该库不支持(无符号)long long
。请参阅邮件列表线程 here (以及几个较旧的)。 Marc Glisse 在回答中还指出,这主要是 Windows 上的问题。
他还建议了一个补丁来支持问题的 C++ 初始化/转换部分 here ,但我在 gmp 的公共(public)开发存储库中还找不到它。正如他在消息中指出的那样,这不会涵盖算术运算等。
关于c++ - 无法在 Windows 下以正常的方式使用 gmp 和 uint64_t,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75036576/