为什么std :: cout打印为4.9999999为5?

时间:2016-07-16 01:28:55

标签: c++ floating-point precision

我正在使用此代码确定log(3)log10(3)之间的区别:

void testPrecisionError() {
    cout
    << log(243) / log(3) << " : "
    << int(log(243) / log(3)) << " : "
    << endl;

    cout
    << log10(243) / log10(3) << " : "
    << int(log10(243) / log10(3)) << " : ")
    << endl;
}

输出结果为:

5 : 4  // I think it is 4.999999 underlying
5 : 5

我发现4.999999打印为5

为什么C ++不像Java那样将它打印为4.99999

我想我再也不能cout让自己相信没有PRECISON LOSS了!

3 个答案:

答案 0 :(得分:3)

因为它舍入到所请求精度的最后一位数的最接近值。实际值约为:

4.99999999999999911182158029987

如果精度为6位,那么5.0000004.999999更近,所以显示5。如果您使用setprecision(16)或更高版本,则会看到所有9个。

当你转向int时,它总是截断,它不会舍入到最接近的值。

至于为什么Java将其显示为4.999999,也许它只会丢弃额外的数字而不是舍入。

答案 1 :(得分:0)

欢迎来到二进制世界,其中实数无法正确表示! doublefloat存在精度问题。因此,在比较2 double个值等时,您需要小心......

例如:

  • sqrt(2) = [real value of sqrt(2)] +/- [precision error]
  • 精度错误取决于您使用的类型/ cpu架构(double,float ...)

答案 2 :(得分:0)

iostreams中的浮点输出由流precision控制。默认的IIRC是小数点右边的6个位置。如果第7位是9,则向上舍入第6位,依此类推。在你的情况下,4.9999999 ...变为5。

IEEE 754中的最大小数精度(可能是您正在使用的小数位数)大约为15位小数。如果您将流的精度设置为16左右(使用setprecision操纵器),您将看到&#34; all&#34;数字。但当然它仍然只是一个近似值,因为浮点数是什么。

为什么它不像Java?两种语言,两套规则。我认为Java错了:如果第7个位置是9,那么4.99999关闭0.0000009+,而5.0关闭仅0.0000001+。您想要更多数字,还是更接近?