对数值进行调整
在Python中对整数和浮点数进行数字计算是很容易的。但是,如果你需要对分数,数组或者日期和时间进行计算,这就会稍微复杂点。对于简单的取整操作,我们可以使用内建的round(value, ndigits)函数就可,举个例子:
>>> round(1.23, 1)
1.2
>>> round(-1.23, 1)
-1.2
>>> round(1.39, 1)
1.4
>>> round(3.1415926535, 3)
3.142
>>>
当某个值恰好等于两个整数间的一半的时候,取整操作会取到离这个值最近的那个偶数上,并且,传递给round()的参数ndigits可以是负数,在这种情况下会相应的取整邻近位数上,举个例子:
>>> a = 31415926535897932626
>>> round(a, -1)
31415926535897932630
>>> round(a, -1)
31415926535897932630
>>> round(a,-2)
31415926535897932600
>>> round(a, -9)
31415926536000000000
>>>
但是注意,在这种情况下只会输出0.0
>>> a = -3.1415926535897932626
>>> round (a, -1)
-0.0
因为后面那个-1实际上就是取的-3四舍五入就等于0了
注意:在对值进行输出的时候不要把取整和格式化的操作混为一谈。如果将数值以固定的位数输出,一般情况下是用不上round()的,相反,我们只要在格式化时指定所需要的精度就可以了。此外,不要采用对浮点数进行取整的方式来进行修正精度上的问题。对于大部分的涉及浮点数的应用程序来说,一般来讲都没必要,但是如果遇到避免出现误差的行为非常重要,那么就可以考虑使用decimal模块
至于四舍五入的运算在IDE上怎么写,可以参考下这个:
def round_num():print(round(1.23, 1))print(round(1.27, 1))print(round(-1.27, 1))print(round(1.25361,3))# 舍入数为负数a = 1627731print(round(a, -1))print(round(a, -2))print(round(a, -3))# 格式化输出x = 1.23456print(format(x, '0.2f'))print(format(x, '0.3f'))print('value is {:0.3f}'.format(x))# 不要自以为是的用round去修正一些精度问题a = 2.1b = 4.2c = a + bprint(c)c = round(c, 2) # "Fix" result (???)print(c)if __name__ == '__main__':round_num()
执行精确的小数计算
关于浮点数,有一个所有人都直到的问题就是它们无法精确表达所有的十进制小数位,并且甚至连简单的数学计算也会引入微小的误差。这些误差实际上是由底层CPU的浮点运算单元和IEEE 754浮点算术标准的一种特性,由于Python的浮点类型保存的数据采用的是原始表示形式,因此这种误差是无法避免的,除非你不用float实例。我们目前能做的就是通过decimal模块来加强精度,但这样会牺牲掉一些性能:
>>> from decimal import Decimal
>>> a = Decimal('1.15')
>>> b = Decimal('1.17')
>>> a + b
Decimal('2.32')
>>> print(a + b)
2.32
>>> (a + b) == Decimal('2.32')
True
>>>
Decimal对象能够以任何你所期待的方式来工作,这个模块的主要功能就是允许控制计算过程中的各个方面,这包括数字的位数和四舍五入。
代码示例:
from decimal import Decimal
from decimal import localcontext
import mathdef acc_deciamal():a = 4.2b = 2.1print(a + b)print((a + b) == 6.3)# 使用decimal模块a = Decimal('4.2')b = Decimal('2.1')print(a + b)print((a + b) == Decimal('6.3'))a = Decimal('1.3')b = Decimal('1.7')print(a / b)with localcontext() as ctx:ctx.prec = 3print(a / b)nums = [1.23e+18, 1, -1.23e+18]print(sum(nums))print(math.fsum(nums))if __name__ == '__main__':acc_deciamal()
对数值进行格式化输出
如果我们需要对一个单独的数值做格式化的输出,就像我前几章讲的那样,直接使用内奸函数format()输出就可:
def format_number():x = 1234.56789# Two decimal places of accuracyprint(format(x, '0.2f'))# Right justified in 10 chars, one-digit accuracyprint(format(x, '>10.1f'))# Left justifiedprint(format(x, '<10.1f'))# Centeredprint(format(x, '^10.1f'))# Inclusion of thousands separatorprint(format(x, ','))print(format(x, '0,.1f'))print(format(x, 'e'))print(format(x, '0.2E'))# stringsprint('The value is {:0,.2f}'.format(x))print(format(x, '0.1f'))print(format(-x, '0.1f'))swap_separators = {ord('.'): ',', ord(','): '.'}print(format(x, ',').translate(swap_separators))if __name__ == '__main__':format_number()
对数值做格式化输出通常都是很直接的,上面的例子既可以用于浮点型整数,也可以用于decimal模块中的Decimal对象。当需要限制数值是位数的时候,数值会根据round()函数的规则来进行取整。注意:对数值加上千位分隔符的格式化操作并不是特定于本地的环境的,当然,如果你需要,应该可以用local模块的函数以及用字符串的translate()方法来交换分隔符。
参考书目:
《Python CookBook》作者:【美】 David Beazley, Brian K. Jones
Github地址:
yidao620c/python3-cookbookgithub.com