2007-08-22

 

Python Cookbook 3.12 十进制小数计算

需求:

你需要进行一些简单的小数计算,但是需要得到定点小数的结果,而不是Python默认的float类型.

讨论:

为了获得最通用,最准确的结果,可以使用decimal模块.
 >>> import decimal
>>> d1 = decimal.Decimal('0.3') # assign a decimal-number object
>>> d1/3 # try some division
Decimal("0.1")
>>> (d1/3)*3 # can we get back where we started?
Decimal("0.3")
对于新使用Python的用户来说(尤其是没有使用别的语言的float类型的用户),经常会对简单的计算结果表示惊奇,比如:
>>> f1 = .3                     # assign a float
>>> f1/3 # try some division
0.099999999999999992
>>> (f1/3)*3 # can we get back where we started?
0.29999999999999999
二进制浮点运算是Python中默认的运算方式.在Python的FAQ中有详细的说明.
很多用户,当然,不喜欢只能使用浮点数,他们需要自定义精度, 或者进行金融计算.而且想获得可预知的结果.
新的decimal模块对你计算过程的上下文进行了很好的控制,它允许你自定义精度,或者保留定义保留小数的方法.当然,如果你只是想进行简单的计算,并获得可以预知的结果,decimal默认的设置就能很好的工作了.
只需要注意几点:你可以传递整数,字符串,元组或者一个decimal对象来创建新的decimal对象,但是如果你想从一个float创建decimal,使用str(n),而不是简单的n.另外 ,decimal对象也可以和别的对象交互(简单的四则运算),如整数,长整数,别的decimal对象,但是不能和float交互.这个限制的强制的.decimal被引入Python,提供了精度控制和结果的可预知性,这都是float所不具有的.如果把一个decimal和一个float共同计算,那么就不能达到目的.decimal对象,可以被转换为别的对象,比如int,long,float等,正如我们期望的那样.
还要注意的是,decimal依然是浮点小数,而不是定点小数,如果你需要使用定点小数,可以参考Tim Peter的FixPoint.同样,Python现在也没有money类型,你可以参考下一节来自己实现一个money类型.最后将一点,不是很明确的,当计算的中间结果产生的小数位多于输入的数字时,你可以保留它的小数一用于后续的计算,当算到最后时在进行小数保留,或者你可以在每一步都保留小数,不同的书中推荐不同的做法,我个人倾向于前者,因为它更简单和方便.

标签:


Comments: 发表评论



<< Home

This page is powered by Blogger. Isn't yours?