【问题标题】:How can I get the exact value of a double?如何获得双精度的确切值?
【发布时间】:2015-11-06 19:29:24
【问题描述】:

我的情况是:

void foo( const double d )
{
    const double rounded_2_decimals = std::round(d*100.0) / 100.0;
    std::cout << "d=" << d << std::endl;
    std::cout << "r=" << rounded_2_decimals << std::endl;
}

打印时为d=3.125,但r=3.12 而不是r=3.13

我怀疑这是因为传入的 d 实际上是 3.1249999.... 这就是我输入初始 cout 的原因,所以我可以看到传入的“真实”值。std::cout 是否舍入值在它显示它们之前?我怎么能看到传入的“真实”值?

【问题讨论】:

  • 我的错,round 总是从零四舍五入。使用std::setprecision,或打印为hexfloat。
  • std::round() 的定义不是从零舍入吗?有没有办法改变“舍入模式”?
  • 你是对的(我将问题误读为 foo(3.125) 打印 3.12),然后没有查找 std::round,因为对该行为的唯一合理解释是四舍五入)跨度>
  • 有谁知道 std::cout 在显示数字之前可能会在哪里记录?我想了解确切的规则。
  • 事实证明我的猜测是正确的。使用 std::precision(25) 时,我注意到这个数字确实比 0.5 舍入限制小一点:3.1249999999999995559107901。

标签: c++ c++11 double rounding gcc5.2


【解决方案1】:

是的,std::cout 对值进行四舍五入,但是您可以设置更高的精度。首先包括 iomanip 标头。那么:

void foo( const double d )
{
    const double rounded_2_decimals = std::round(d*100.0) / 100.0;
    std::cout << "d=" << std::setprecision(9) <<  d << std::endl;
    std::cout << "r=" << std::setprecision(9) << rounded_2_decimals << std::endl;
}

现场示例程序here

【讨论】:

  • 诀窍是将 std::setprecision(9) 与 std::fixed 结合使用。
  • std::fixed 不是获得“真实”值所必需的,因为 std::precision 足以提供更高的精度,指定覆盖小数点两侧的最大位数。结果将忽略小于指定最大位数的尾随零。但是,如果您想要特定的格式,例如小数点后的固定位数,或者想要指定小数点后位数的精度,那么可以,您可以将其与std::fixed
  • 谢谢,ccoder83。尾随零的截断使我走错了路。增加std::setprecision() 中的值最终向我展示了我的怀疑,该值只是比四舍五入所需的 0.5 小一点。
  • @Stéphane 如果它在 1.0 和 2.0 之间,最多可能需要 53 位才能看到整个值,如果小于 1.0 则更多。
猜你喜欢
  • 1970-01-01
  • 2017-06-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-07
  • 2023-03-05
相关资源
最近更新 更多