问题描述
$ printf "%0.2f\n" 41.495
41.49
$ printf "%0.2f\n" 41.485
41.49
$ printf "%0.2f\n" 41.475
41.47
$ printf "%0.2f\n" 41.465
41.47
$ printf "%0.2f\n" 41.455
41.46
$ printf "%0.2f\n" 41.445
41.44
$ printf "%0.2f\n" 41.435
41.44
$ printf "%0.2f\n" 41.425
41.42
$ printf "%0.2f\n" 41.415
41.42
$ printf "%0.2f\n" 41.405
41.40
为什么第二位小数位数不均的数字不能正确四舍五入,而偶数则是四舍五入?此外,.445永远无法取整的问题是什么?
Why are the numbers with an uneven number as the second decimal not correctly rounded and even ones are? Additionally what is wrong with .445 that it never gets rounded?
推荐答案
它与浮点数有关,但与双精度无关.
It has to do with floating-point, but not with double-precision.
写作时
printf "%0.2f\n" 41.495
在系统上,printf
首先将41.495
舍入到最接近的x87 80位浮点数[1].这是如何运作的?首先以二进制形式写入41.495:
on your system, printf
first rounds 41.495
to the closest x87 80-bit floating-point number[1]. How does that work? First write 41.495 in binary:
b101001.0111 11101011100001010001 11101011100001010001 11101011100001010001 ...
(分开的组无限重复).现在,我们将此数字舍入为64位二进制数字:
(the separated groups repeat ad infinitum). Now we round this number to have 64 binary digits:
b101001.0111111010111000010100011110101110000101000111101011100001
这是printf实际格式化的数字.用十进制表示,完全是:
This is the number that is actually formatted by printf. Written in decimal, it is exactly:
41.4949999999999999990285548534529880271293222904205322265625
如您所见,它仅比41.495小一点,因此,当printf将其四舍五入为两位小数位时,会将其四舍五入为 ,并打印41.49
.
as you can see, it is just a little bit less than 41.495, so when printf rounds it to two fractional digits, it rounds down, and 41.49
is printed.
现在看41.485;四舍五入到64位二进制数字后,我们得到的值是:
Now look at 41.485; after rounding to 64 binary digits, we get the value:
41.48500000000000000055511151231257827021181583404541015625
比41.485稍大,因此printf将其四舍五入 .
在我的系统上,printf管理中有一个关于此的警告:
On my system, there is a warning about this in the printf manage:
- bash并非在所有操作系统上都使用x87格式(实际上,并非在所有体系结构上都可用);在某些其他系统上,这些值将被解释为双精度(因此四舍五入为53位而不是64位),结果将有所不同.
这篇关于Shell中的浮点舍入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!