python中小数_比较python中的小数

I want to be able to compare Decimals in Python. For the sake of making calculations with money, clever people told me to use Decimals instead of floats, so I did. However, if I want to verify that a calculation produces the expected result, how would I go about it?

>>> a = Decimal(1./3.)

>>> a

Decimal('0.333333333333333314829616256247390992939472198486328125')

>>> b = Decimal(2./3.)

>>> b

Decimal('0.66666666666666662965923251249478198587894439697265625')

>>> a == b

False

>>> a == b - a

False

>>> a == b - Decimal(1./3.)

False

so in this example a = 1/3 and b = 2/3, so obviously b-a = 1/3 = a, however, that cannot be done with Decimals.

I guess a way to do it is to say that I expect the result to be 1/3, and in python i write this as

Decimal(1./3.).quantize(...)

and then I can compare it like this:

(b-a).quantize(...) == Decimal(1./3.).quantize(...)

So, my question is: Is there a cleaner way of doing this? How would you write tests for Decimals?

解决方案

You are not using Decimal the right way.

>>> from decimal import *

>>> Decimal(1./3.) # Your code

Decimal('0.333333333333333314829616256247390992939472198486328125')

>>> Decimal("1")/Decimal("3") # My code

Decimal('0.3333333333333333333333333333')

In "your code", you actually perform "classic" floating point division -- then convert the result to a decimal. The error introduced by floats is propagated to your Decimal.

In "my code", I do the Decimal division. Producing a correct (but truncated) result up to the last digit.

Concerning the rounding. If you work with monetary data, you must know the rules to be used for rounding in your business. If not so, using Decimal will not automagically solve all your problems. Here is an example: $100 to be share between 3 shareholders.

>>> TWOPLACES = Decimal(10) ** -2

>>> dividende = Decimal("100.00")

>>> john = (dividende / Decimal("3")).quantize(TWOPLACES)

>>> john

Decimal('33.33')

>>> paul = (dividende / Decimal("3")).quantize(TWOPLACES)

>>> georges = (dividende / Decimal("3")).quantize(TWOPLACES)

>>> john+paul+georges

Decimal('99.99')

Oups: missing $.01 (free gift for the bank ?)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值