我正在使用此代码确定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了!
答案 0 :(得分:3)
因为它舍入到所请求精度的最后一位数的最接近值。实际值约为:
4.99999999999999911182158029987
如果精度为6位,那么5.000000
比4.999999
更近,所以显示5
。如果您使用setprecision(16)
或更高版本,则会看到所有9个。
当你转向int
时,它总是截断,它不会舍入到最接近的值。
至于为什么Java将其显示为4.999999
,也许它只会丢弃额外的数字而不是舍入。
答案 1 :(得分:0)
欢迎来到二进制世界,其中实数无法正确表示! double
和float
存在精度问题。因此,在比较2 double
个值等时,您需要小心......
例如:
sqrt(2) = [real value of sqrt(2)] +/- [precision error]
答案 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+。您想要更多数字,还是更接近?