提问人:Bunny 提问时间:10/9/2018 最后编辑:Jonathan LefflerBunny 更新时间:10/9/2018 访问量:178
C++ 不截断双精度?
C++ not truncating doubles?
问:
我的代码:
运行以下代码的结果:
#include <cstdio>
//i define printBits elsewhere but that's not relevant to my question
void printBits(const float f);
void printBits(const double f);
int main(int argc, char **argv) {
float f=4.2;
double d=4.2;
printf("float: %20.20f\n",f);
printBits(f);
printf("double: %50.50f\n",d);
printBits(d);
return 0;
}
是:
float: 4.19999980926513671875
0 10000001 00001100110011001100110
double: 4.20000000000000017763568394002504646778106689453125
0 10000000001 0000110011001100110011001100110011001100110011001101
请注意,我如何将 和 都设置为 4.2,但浮点值略小于 4.2,double 值略大于 4.2。我明白为什么浮点值小于 4.2;4.2 值被截断为小于 4.2 的值 ~2^-21。但是,我不明白为什么双精度值略大于 4.2。我以为浮点数和双精度值只会截断,但似乎双精度值是向上舍入而不是向下舍入。f
d
一般来说,浮点数和双精度是否四舍五入到最接近的可表示值?浮动和双打的圆度不同吗?我尝试搜索这个,但找不到任何相关的东西。
答:
6赞
Mark Ransom
10/9/2018
#1
浮点值不会被截断,而是会四舍五入到最接近的可表示值。您发现了一个有趣的示例,其中舍入的方向不同,具体取决于浮点的大小,但这种情况并不少见;您可以预期舍入在大约 50% 的时间内上升,在 50% 的时间内下降,少数值是完全可表示的,根本不是舍入的。例如,4.25 是确切的。
评论
2赞
Eric Postpischil
10/9/2018
我认为易于可视化的示例可能很有用。例如,如果可以表示 0、1/4、1/2、3/4 和 1,并且可以表示 0、1/8、1/4、3/8、1/2、5/8、3/4、7/8 和 1,则将 .6 转换为将向下舍入为 1/2(更接近 .5 而不是 .75),但将 .6 转换为将向上舍入为 5/8(更接近 .625 而不是 .5)。float
double
float
double
评论
<cstdio>