Boost Multiprecision精度舍入问题:乘法结果不符合预期
问题
我想要计算数字123456789.123456789与1000000000.0的乘积,预期结果是整数123456789123456789或浮点数123456789123456789.0,但实际得到的结果是:
res: 123456789123456791.04328155517578125
int_res: 123456789123456791
请问是否需要换其他方式实现?
现有代码
#include <iostream> #include <boost/multiprecision/cpp_int.hpp> #include <boost/multiprecision/cpp_dec_float.hpp> namespace bmp = boost::multiprecision; int main() { bmp::cpp_dec_float_100 scalar{1000000000.0}; bmp::cpp_dec_float_100 a{123456789.123456789}; bmp::cpp_dec_float_100 res = a * scalar; bmp::cpp_int int_res = res.convert_to<bmp::cpp_int>(); std::cout << " res: " << res.str() << std::endl; std::cout << "int_res: " << int_res.str() << std::endl; return 0; }
解决方案
问题根源是用double字面量初始化cpp_dec_float_100时,double无法精确表示123456789.123456789,导致初始值就有精度损失,最终乘积出错。可以用以下两种方法解决:
方法1:使用字符串字面量初始化高精度浮点数
通过字符串传递初始值,绕过double的精度限制:
#include <iostream> #include <boost/multiprecision/cpp_int.hpp> #include <boost/multiprecision/cpp_dec_float.hpp> namespace bmp = boost::multiprecision; int main() { bmp::cpp_dec_float_100 scalar{"1000000000.0"}; bmp::cpp_dec_float_100 a{"123456789.123456789"}; bmp::cpp_dec_float_100 res = a * scalar; bmp::cpp_int int_res = res.convert_to<bmp::cpp_int>(); std::cout << " res: " << res.str() << std::endl; std::cout << "int_res: " << int_res.str() << std::endl; return 0; }
运行后会输出预期的123456789123456789.0和对应的整数结果。
方法2:拆分整数与小数部分,全程用整数运算
既然最终目标是整数结果,直接拆分原数的整数和小数部分,用高精度整数完成计算,彻底规避浮点数精度问题:
#include <iostream> #include <boost/multiprecision/cpp_int.hpp> namespace bmp = boost::multiprecision; int main() { bmp::cpp_int integer_part = 123456789; bmp::cpp_int decimal_part = 123456789; // 对应原数小数部分乘以1e9的结果 bmp::cpp_int scalar = 1000000000; bmp::cpp_int int_res = integer_part * scalar + decimal_part; std::cout << "int_res: " << int_res.str() << std::endl; return 0; }
该方法直接得到精确的整数结果123456789123456789。
内容的提问来源于stack exchange,提问作者bladzio
相关产品推荐
相关产品推荐

