[英]How to assign min of uint32_t::max and uint64_t in type safe manner?
[英]Unable to work with gmp and uint64_t under windows in a sane manner
以下代碼在 Linux/Debian (g++ 10.2) 下運行良好(編譯,斷言語句為真),但拒絕在 Windows (mingw64 g++ 12.2.0) 下運行。 它基本上只是應該將UINT64_MAX
分配給gmp庫中的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); }
__gmp_expr(unsigned long long int l) { init_ui(l); }
都很好,只是這對我來說太臟了。
除了按照user17732522 的回答中的建議修補 gmp 庫之外,還可以通過使用轉換助手 function 讓我的示例工作。像這樣:
/// Helper for converting anything to mpf_class.
namespace bigdec {
template<typename T> [[nodiscard]] inline
mpf_class get(const T& num) {
std::stringstream ss;
ss << num;
mpf_class bigdec;
bigdec.set_str(ss.str(), 10);
return bigdec;
}}
並相應地改變用法:
int main() {
mpf_class y = bigdec::get(UINT64_MAX); // <- here
y *= bigdec::get(UINT64_MAX); // <- and here
assert(mpf_class_to_str(y) == "340282366920938463426481119284349108225");
}
現在它編譯並且斷言在我的 Linux 和 Windows 環境中都為真。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.