boost多精度库与模数不一致
Inconsistency in boost multiprecision library with modulus
我发现使用cpp_int的boost多精度库有一些不一致,我想知道问题是否在我这边?我做错什么了吗?
boost::multiprecision::cpp_int value("845812507058753702096720396260955981034309941487979439207575316627396775257009179367680598562088782400182102510047921049667535737841056751035898984440045398065941794853342721440022891483618946596390530332584847468817849746783423105644934675762519035784877729169739110084935079201004991911753548016158266946593610497793934212345180527788034865286995713462176706647193473406223095268503330593499438446017000593156395272905592017851490768402042283892535127698736772114426168690580061412400354553387531076676433901465842118416610671452446364936252601684680593015917270112975907856081311621268680168563153055479531193987696015767888543608430149655940111761214342848772129089336344636193634262254610730");
boost::multiprecision::cpp_int residueResult = value % 733;
std::cout << residueResult; // this prints out 4
int residue1 = residueResult.convert_to<int>(); // this is 4
int residue2 = int(value % 733); // this is 1
为什么在执行int(值%733(时会给出一个值1?
这与boost 1.59.0和visual studio 2013社区有关。
当前的问题是value % 733
是某种实现细节代理类型,不能仅将其转换为int
。事实上,它甚至不使用gcc和clang进行编译,正如您所看到的,它在MSVC中产生了无稽之谈。要绕过这一点,请在施放之前转换回cpp_int
int main () {
boost::multiprecision::cpp_int value("845812507058753702096720396260955981034309941487979439207575316627396775257009179367680598562088782400182102510047921049667535737841056751035898984440045398065941794853342721440022891483618946596390530332584847468817849746783423105644934675762519035784877729169739110084935079201004991911753548016158266946593610497793934212345180527788034865286995713462176706647193473406223095268503330593499438446017000593156395272905592017851490768402042283892535127698736772114426168690580061412400354553387531076676433901465842118416610671452446364936252601684680593015917270112975907856081311621268680168563153055479531193987696015767888543608430149655940111761214342848772129089336344636193634262254610730");
boost::multiprecision::cpp_int residueResult = value % 733;
std::cout << residueResult << "n"; // this prints out 4
int residue1 = residueResult.convert_to<int>(); // this is 4
int residue2 = static_cast<int>(boost::multiprecision::cpp_int(value % 733));
std::cout << residue1 << "n" << residue2;
}
这将打印
4
4
4
根据需要。
第二个强制转换无效,不应编译。
GCC
test.cpp|9 col 35| error: invalid cast from type ‘boost::enable_if_c<true, boost::multiprecision::detail::expression<boost::multiprecision::detail::modulus_immediates, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<> >, int, void, void> >::type {aka boost::multiprecision::detail::expression<boost::multiprecision::detail::modulus_immediates, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<> >, int, void, void>}’ to type ‘int’
|| int residue2 = int(value % 733); // this is 1
叮当声
test.cpp|9 col 20| error: cannot convert 'typename enable_if_c<is_compatible_arithmetic_type<int, number<cpp_int_backend<0, 0, boost::multiprecision::cpp_integer_type::signed_magnitude, boost::multiprecision::cpp_int_check_type::unchecked, allocator<unsigned long long> >, et_on> >::value && (number_category<cpp_int_backend<0, 0, boost::multiprecision::cpp_integer_type::signed_magnitude, boost::multiprecision::cpp_int_check_type::unchecked, allocator<unsigned long long> > >::value == number_kind_integer), detail::expression<detail::modulus_immediates, number<cpp_int_backend<0, 0, boost::multiprecision::cpp_integer_type::signed_magnitude, boost::multiprecision::cpp_int_check_type::unchecked, allocator<unsigned long long> >, et_on>, int> >::type' (aka 'boost::multiprecision::detail::expression<boost::multiprecision::detail::modulus_immediates, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0, 0, boost::multiprecision::cpp_integer_type::signed_magnitude, boost::multiprecision::cpp_
|| nt_check_type::unchecked, std::__1::allocator<unsigned long long> >, boost::multiprecision::expression_template_option::et_on>, int, void, void>') to 'int' without a conversion operator
|| int residue2 = int(value % 733); // this is 1
|| ^~~~~~~~~~~~~~~
推测
如果您实际上以不同的方式编写了这篇文章,那么您可能得到了一个reinterpret_cast,因此结果就是实现定义的。
更新
致评论:
在Coliru上直播
#include <boost/multiprecision/cpp_int.hpp>
#include <cstdio>
int main() {
using Int = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<>, boost::multiprecision::et_off>;
Int value("845812507058753702096720396260955981034309941487979439207575316627396775257009179367680598562088782400182102510047921049667535737841056751035898984440045398065941794853342721440022891483618946596390530332584847468817849746783423105644934675762519035784877729169739110084935079201004991911753548016158266946593610497793934212345180527788034865286995713462176706647193473406223095268503330593499438446017000593156395272905592017851490768402042283892535127698736772114426168690580061412400354553387531076676433901465842118416610671452446364936252601684680593015917270112975907856081311621268680168563153055479531193987696015767888543608430149655940111761214342848772129089336344636193634262254610730");
printf("residue %d:n", int(value % 733));
}
打印
residue 4:
相关文章:
- 大于65535的C++数组[size]引发不一致的溢出
- 在 C++(和 C)中进行类型转换时明显不一致
- 填充上编译器生成的复制构造函数之间的不一致
- 犰狳的 print() 方法和 cout 在从 Rcpp 调用时顺序不一致
- CreateDIBSection为同一图像返回不一致的位图位值
- 在 Qml 中从 QSqlTableModel 中删除单行时视图不一致
- 模板参数推导不一致
- 声明中不一致的no是否违反ODR?
- 如何删除分支因子不一致的树,最大为 30,40
- 在不损失精度的情况下将double从C++传输到python
- 从 C++ 函数与 Python 函数返回的不一致值用于偏斜正态分布
- 从 C 字符串构造 std::string 与从另一个 std::string 构造 std::string 不一致
- 这种比较是否不一致(或者存在其他问题)?
- 以下可变参数模板行为是否不一致?
- 如何修复我的链表读数不一致的问题?
- 在C++17中,为什么类模板和函数模板的指针类型推导明显不一致
- 有没有一种方法可以在不设置精度的情况下设置小数位数
- 二进制文件的大小不一致,双精度 (C/C++)
- 双精度数组和结果与 WIN32 和 WIN64 上的C++不一致
- boost多精度库与模数不一致