Python数值处理一

30次阅读

共计 1416 个字符,预计需要花费 4 分钟才能阅读完成。

round()取整

使用 round() 函数可以轻松的对浮点数进行取整操作。示例如下:

>>> round(1.23, 1)
1.2
>>> round(1.27, 1)
1.3
>>> round(-0.36, 1)
-0.4

round()第二个参数可以是负数:

>>> a = 13849
>>> round(a, -1)
12850
>>> round(a, -2)
13800

但是要注意,这里有两个很奇怪的例子:

>>> round(2.5)
2
>>> round(0.5)
0

可以发现,这里完全没有按照我们所熟悉的 四舍五入 的取整规则来。这是因为 round() 函数在应对这种与两个整数距离相同的情况时,会取到 最近的偶数 上去。

同时官方文档中还举了一个例子,

Note The behavior of round() for floats can be surprising: for example, round(2.675, 2) gives 2.67 instead of the expected 2.68. This is not a bug: it’s a result of the fact that most decimal fractions can’t be represented exactly as a float. See Floating Point Arithmetic: Issues and Limitations for more information.

round(2.675, 2)的结果居然是 2.67,这个的原因是浮点数表示是有误差的,2.675 在计算机上实际上不是准确的 2.675。

解释一下浮点数问题

首先我们要明确一个概念,计算机只能识别 二进制 ,也就是一堆10的组合,但是人类常用的却是十进制。
十进制的数在计算机里就需要转换成二进制表示,在将十进制整数转为二进制的时候,往往是将原数不断 除以 2 ,直到商小于 1,将每一次得到的 余数逆序排列 ,就能得到这个整数的二进制表示了。
到了小数部分,我们采用的是乘以 2,取整数部分,直到小数部分为 0 ,顺序排列。但是有些特殊的数就要搞事情了。

0.1 * 2 = 0.2 => 0
0.2 * 2 = 0.4 => 0
0.4 * 2 = 0.8 => 0
0.8 * 2 = 1.6 => 1
0.6 * 2 = 1.2 => 1
0.2 * 2 = 0.4 => 0
0.4 * 2 = 0.8 => 0
0.8 * 2 = 1.6 => 1
...

发现没有,进入无限循环了,也就是说整数中一些小数,在二进制表示的时候是 无限循环小数 ,但是在计算机中毕竟是用 有限位 来表示一个值的,这就造成了有些小数(浮点数)在计算机中是被截掉部分的,这就是浮点数不精确的原因啦。

decimal

如果你特别需要精确的数值,那么可以使用 decimal 模块。当然这是有性能代价的(有得必有失嘛)。
举个例子:

>>> a = 4.2
>>> b = 2.1
>>> a + b
6.300000000000001
>>> (a+b) == 6.3
False
# 这次试试 decimal
>>> from decimal import Decimal
>>> a = Decimal('4.2')
>>> b = Decimal('2.1')
>>> a + b
Decimal('6.3')
>>> print(a+b)
6.3
>>> (a + b) == Decimal('6.3')
True

数值的输出格式化

如果只是想让数值以固定的位数输出,那么是用不着 round() 的。

>>> a = 1.23456
>>> format(a, '0.2f')
'1.23'
>>> format(a, '0.3f')
'1.234'

欢迎关注个人公众号 公子政的宅日常 查看更多文章:

正文完
 0