C++中的setprecision是否会四舍五入?如果是,为什么会出现这种情况?

13
以下代码片段输出0.29847,我本来希望它输出0.29848:
double f = 0.298475;
cout << setprecision(5) << f << endl;

然而,对于其他示例,我观察到进行了四舍五入:

double f = 0.123459;
cout << setprecision(5) << f << endl;

输出:0.12346

double f = 0.123454;
cout << setprecision(5) << f << endl;

输出: 0.12345

2个回答

21

数字0.298475double中无法准确表示(因为它不是分母为2的幂次方的分数,而是11939/40000),实际存储的数字实际上更接近于0.29847而不是0.29848。


5
确切地说,是0.298474999999999990318855225268634967505931854248046875。 - dan04
2
换句话说,实际上有两个舍入步骤:一个是当文字“0.298475”被转换为“double”时,另一个是在将某些数字打印到“cout”时舍入。 - aschepler
2
@dan04:这是一个有些毫无意义的显示;一个64位IEEE754浮点数只包含约17个十进制数字的信息... - Kerrek SB
@KerrekSB 但是由于它是一个有理数,其分母可以被10的幂整除,因此它可以被准确地表示为十进制数。这样做通常有助于消除关于浮点数舍入和显示行为的误解。 - Daniel Fischer
@DanielFischer:做什么有用呢?请注意,我们从一个有限的十进制表示开始,因此我们必须有一个有理数,其分母可以被10的某个幂整除。 - Kerrek SB
1
展示输入被转换为的确切数字可能是有用的。如果您提供了17个有效数字,有些人会认为您得到了17个十进制数字,而不是53个二进制数字。因此,给出精确的值并说“这是分子/2 ^指数”可能有助于传达观点。有时候。 - Daniel Fischer

0

从文档中我所看到的,setprecision() 函数并不执行任何舍入操作,而只是设置小数点后显示的最大位数。double 和 float 数字的可能表示方式可能与您使用的常量初始化器不同。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接