Kos*_*mos 9 c++ floating-point digits ieee-754 floating-point-precision
我有这个简单的代码行:
float val = 123456.123456;
Run Code Online (Sandbox Code Playgroud)
当我打印此val或查看范围时,它存储值123456.13
好吧,没关系,它不能在4个字节之后存储所有那些数字,但为什么它在点之后产生13?不应该是12吗?
(在win32上使用vc ++ 2010 express)
Ric*_*gan 10
在二进制中,123456.123456是11110001001000000.000111111001 ...(无限).它舍入到11110001001000000.001或123456.125.这在打印时四舍五入为123456.13.
存储的值val等于123456.125.你得到了,.13因为你正在四舍五入:
float val = 123456.123456;
printf("%.4f %.2f\n", val, val);
Run Code Online (Sandbox Code Playgroud)
输出: 123456.1250 123456.13
在这种情况下,您应该使用double来避免截断.编译器还应该警告你:"警告C4305:'初始化':从'double'截断到'float'".
当表示为浮点数时,您的数字的指数为16(即该值是其尾数乘以2 ^ 16或65536).然后螳螂变成了
123456.123456 / 65536 = 1.8837909462890625
Run Code Online (Sandbox Code Playgroud)
为了适应32位浮点数,mantisse被截断为23位,所以现在变成了1.883791.当乘以时65536,它变成了123456.125.
请注意5小数点后的第三个位置:您使用的C++的输出例程将其舍入,使您的最终数字看起来像123456.13.
编辑四舍五入的解释:(瑞克里根的评论)
舍入首先以二进制(24位),十进制到二进制转换,然后到十进制,in printf.储存值为1.1110001001000000001 x 2 ^ 16 = 1.8837909698486328125 x 2 ^ 16 = 123456.125.它打印为123456.13,但仅仅因为Visual C++使用"从零开始的一半"舍入.
如果你想玩其他数字和浮动表示,这是一个非常有用的IEEE-754计算器.
| 归档时间: |
|
| 查看次数: |
910 次 |
| 最近记录: |