c++ - 为什么来自 MSYS2 的 GNU MP (gmplib) 意外地将 ull 转换为 32 位整数?
问题描述
我正在使用 MSYS2(64 位)将我的 c++ 代码从 Linux 移植到 Windows。关键库是 GNU MP (gmplib)。以下代码在 MSYS2/MinGW64 环境中给出了错误的结果,而在 Ubuntu 中工作正常。mpz_set_ui
显然,在使用函数时,会出现从 64 位整数到 32 位整数的不需要的转换。
#include <iostream>
#include <gmp.h>
int main() {
std::cout << "GMP version: " << __gmp_version << std::endl;
std::cout << "GMP_LIMB_BITS: " << GMP_LIMB_BITS << std::endl;
unsigned long long a = UINT64_MAX;
std::cout << a << std::endl;
mpz_t mpz;
mpz_init(mpz);
mpz_set_ui(mpz, a);
unsigned long long b = mpz_get_ui(mpz);
std::cout << b << std::endl;
}
Ubuntu正确输出:
GMP version: 6.2.0
GMP_LIMB_BITS: 64
18446744073709551615
18446744073709551615
MSYS2/MinGW64 意外转换:
GMP version: 6.2.1
GMP_LIMB_BITS: 64
18446744073709551615
4294967295
重现行为的步骤:
- 全新安装 MSYS2(64 位)。
Getting Started
来自https://www.msys2.org/的步骤在 MSYS2 环境中运行:
吃豆人-Syu
吃豆人-苏
pacman -S --需要基础开发 mingw-w64-x86_64-toolchain
- 使用静态链接在 MinGW64 环境中编译:
g++ -MT .o/main.o -MD -MP -MF .d/main.Td -std=c++17 -g -Wall -Wextra -pedantic -c -o .o/main.o main.cpp mv -f .d/main.Td .d/main.d g++ -static -o main .o/main.o -lgmp
main.d 按预期指向 C:/msys64/mingw64/include/gmp.h 并且我验证 C:\msys64\mingw64\lib\libgmp.a 用于链接,并且不存在其他版本的 gmplib.a的子文件夹C:/msys64
我还使用以下方法自定义构建了 GNU MP 库:
。/配置
制作
进行安装
然而,不需要的转换仍然存在。我可能会错过一些基本的东西,但我不知所措。这是我在 Stackoverflow 上的第一个问题,非常感谢您的帮助。
解决方案
该mpz_get_ui()
函数返回一个unsigned long
,而不是一个unsigned long long
。
在 Linux/GCC 上,unsigned long
是一个 64 位的值,但是 C++ 标准只要求unsigned long
支持高达 的值4'294'967'295
,这可以通过 32 位整数来满足。Linux 允许更大的值,但 Windows 上的 MSVC 和 MinGW 将使用 32 位整数来表示unsigned long
. 这意味着在 Windows 上,您的 64 位输入值mps_set_ui()
将降级为 32 位值。
因此,两个编译器的行为都是正确的,您已经绊倒了特定于平台的实现细节。
如果您希望在任何地方都允许使用 64 位整数,您应该使用固定位宽整数类型(例如,uint64_t
而不是unsigned long
),但不幸的是,这仍然不允许您mp_set_ui
在 Windows 上指定 64 位整数。
推荐阅读
- excel - 在 Excel 中,可以编写哪个公式可以轻松识别我的输出条件是真还是假
- laravel - 如何在 laravel 7 中的 eloquent 模型后回显最后一个查询?
- python - 有没有办法按数据框的值对数据框进行分组?
- c# - 具有多级子级的实体框架核心父/子清理查询
- typescript - 使用 typescript-eslint 在 VSCode 编辑器中未显示 Typescript 错误
- c# - 比较对象与字典
> 考虑性能 c# - html - MathJax - 具有 id 或类的对齐方程
- dafny - Dafny:不检查多个谓词
- php - PHP:如何将动态构建的查询迁移到 MySQLi Prepared Statements?
- python - ''more'' 不是内部或外部或命令、可运行程序或批处理文件