对某些标准流类插入和提取浮点数是否保留其值?

edolor 发布于 2019-03-09 c++ 最后更新 2019-03-09 14:31 0 浏览

当我调试我有时想打印由函数返回的浮点数并将其用作另一个函数的输入值。我想知道什么是指导浮点数格式化的默认参数。 在下面的代码中f1和f2总是相同的吗?

#include <sstream>
#include <cassert>
int main(int argc, const char *argv[])
{
  std::stringstream ss;
float f1 = .1f;
  ss << f1;
float f2;
  ss >> f2;
assert(f1 == f2);
  return 0;
}
我可以写一堆浮点数到std :: cout或std :: ofsteam,并读回它们以得到完全相同的数字,或者我应该明确地设置小数点后面的数字数量(例如,建议here? 令我困扰的是,虽然.1不能表示为二进制分数,但它仍然由标准流正确格式化。
已邀请:

paut

赞同来自:

不必要。默认情况下,ostream输出6位数字 精确。为了能够“往返”漂浮,你需要 精度为std::numeric_limits<float>::max_digits10(其中 是最常见的代表9。如果是流 用于坚持,你只是坚持浮动, 只需在写任何东西之前设置精度,例如:

ss.precision( std::numeric_limits<float>::max_digits10 );
(如果你需要同时处理floatdouble,并且不想要 float上的额外数字,您需要设置精度 每次输出浮点值。)

amodi

赞同来自:

更重要的是,断言(f1 == f2);当f1和f2都是浮点数时很少是正确的。你想要像assert(abs(f1 - f2)< tolerance);有几种常用于选择公差的技术。您应该使用哪一个取决于您的程序正在解决的问题。

benim

赞同来自:

不,他们不能保证是一样的。 发生的事情是浮动本身具有比默认打印更高的精度,因此只要您读入的有效数字少于默认输出精度,您打印出来的内容(至少通常)将被舍入回到你读到的价值。 但是,如果您拥有使用float的完整精度的数据,并且您已将其读入并以完全精度将其写回,则您将开始看到差异。

#include <sstream>
#include <iomanip>
#include <iostream>
int main() { 
    std::istringstream buffer("0.1");
    float value;
    buffer >> value;
    std::cout << value << "\n"; 
    std::cout << std::setprecision(10) << value;
}
结果:
0.1
0.1000000015
在这种情况下,尾随的15(大约)是0.1和我编译器的float可以表示的最接近的差值。