我正在尝试这个:
std::cout << boost::lexical_cast<std::string>(0.0009) << std::endl;
并期望输出为:
0.0009
但输出是:
0.00089999999999999998
g++ 版本:5.4.0,升压版本:1.66
我能做些什么来让它打印出它得到的东西。
我正在尝试这个:
std::cout << boost::lexical_cast<std::string>(0.0009) << std::endl;
并期望输出为:
0.0009
但输出是:
0.00089999999999999998
g++ 版本:5.4.0,升压版本:1.66
我能做些什么来让它打印出它得到的东西。
您实际上可以覆盖默认精度:
#include <boost/lexical_cast.hpp>
#ifdef BOOST_LCAST_NO_COMPILE_TIME_PRECISION
# error unsupported
#endif
template <> struct boost::detail::lcast_precision<double> : std::integral_constant<unsigned, 5> { };
#include <string>
#include <iostream>
int main() {
std::cout << boost::lexical_cast<std::string>(0.0009) << std::endl;
}
印刷
0.0009
但是,这既不受支持 ( detail::
) 也不灵活(现在所有双打都会以这种方式出现)。
问题是从十进制表示转换为二进制表示会丢失准确性。相反,使用十进制浮点表示:
#include <boost/lexical_cast.hpp>
#include <boost/multiprecision/cpp_dec_float.hpp>
#include <string>
#include <iostream>
using Double = boost::multiprecision::cpp_dec_float_50;
int main() {
Double x("0.009"),
y = x*2,
z = x/77;
for (Double v : { x, y, z }) {
std::cout << boost::lexical_cast<std::string>(v) << "\n";
std::cout << v << "\n";
}
}
印刷
0.009
0.009
0.018
0.018
0.000116883
0.000116883
boost::lexical_cast
将浮点数转换为其字符串表示时,不允许您指定精度。从文档
对于更多涉及的转换,例如精度或格式需要比默认行为提供的更严格的控制
lexical_cast
,建议使用传统std::stringstream
方法。
所以你可以使用stringstream
double d = 0.0009;
std::ostringstream ss;
ss << std::setprecision(4) << d;
std::cout << ss.str() << '\n';
或者另一种选择是使用boost::format
库。
std::string s = (boost::format("%1$.4f") % d).str();
std::cout << s << '\n';
0.0009
是一个双精度浮点文字,假设 IEEE754,值
0.00089999999999999997536692664112933925935067236423492431640625
这就是boost::lexical_cast<std::string>
函数参数。格式化程序中的默认精度设置cout
是四舍五入到第 17 位有效数字:
0.00089999999999999998
真的,如果你想要精确的小数精度,那么使用小数类型(Boost 有一个),或者使用整数并自己拼接小数分隔符。但在您的情况下,鉴于您只是在没有复杂计算的情况下输出数字,四舍五入到第 15 位有效数字将产生预期的效果:
std::setprecision(15)
进入输出流。