Shell中的浮点舍入 [英] Floating point rounding in shell

查看:121
本文介绍了Shell中的浮点舍入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

$ 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:

由于浮点数从ASCII转换为浮点然后再返回,浮点精度可能会丢失.

Since the floating point numbers are translated from ASCII to floating-point and then back again, floating-point precision may be lost.


  1. bash并非在所有操作系统上都使用x87格式(实际上,并非在所有体系结构上都可用);在某些其他系统上,这些值将被解释为双精度(因此四舍五入为53位而不是64位),结果将有所不同.

这篇关于Shell中的浮点舍入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆