我很好奇哪一个更适合作为货币领域?我会做一些简单的操作,比如差价,新旧价格之间的百分比。我计划在零(即10.50)之后保留两位数,如果这些数字为零,则保留大部分时间,我将隐藏这些数字并将其显示为“10”
ps:货币不是基于美元的:)
答案 0 :(得分:107)
始终使用DecimalField
来赚钱。即使是简单的操作(加法,减法)也不能免于浮动舍入问题:
>>> 10.50 - 0.20
10.300000000000001
>>> Decimal('10.50') - Decimal('0.20')
Decimal('10.30')
答案 1 :(得分:44)
问题的答案是正确的,但有些用户会偶然发现这个问题,找出DecimalField和FloatField之间的区别。 Seth提出的浮动舍入问题是货币问题。
Django Docs States
FloatField类有时与DecimalField类混合在一起。虽然它们都代表实数,但它们以不同的方式表示这些数字。 FloatField在内部使用Python的float类型,而DecimalField使用Python的Decimal类型。 阅读更多here。
以下是两个字段之间的其他差异:
DecimalField:
更多关于DecimalField from the Django Docs。
FloatField:
更多关于FloatField from the Django Docs。
适用于两者:
我在寻找两个字段之间的区别时遇到了这个问题,所以我认为这对那些处于同样情况的人有帮助:)
更新:要回答这个问题,我认为你可以侥幸地代表货币,尽管十进制更适合。当它计算浮动时存在舍入问题,因此您必须使用round(value, 2)
以便将浮点表示舍入到小数点后两位。这是一个简单的例子:
>>> round(1.13 * 50 + .01, 2)
56.51
你仍然可以遇到浮动和回合问题。就像在这里一样,我们看到它的值为5:
>>> round(5.685, 2)
5.68
但是在这种情况下,它会围捕:
>>> round(2.995, 2)
3.0
它与浮点数如何存储在内存中有关。请参阅here。
答案 2 :(得分:6)
编辑:Satchmo项目不再有效,请查看处理货币的这些替代方案
基于Django的Satchmo Project有一个CurrencyField和CurrencyWidget,值得一看。
查看satchmo_utils app目录中的源
答案 3 :(得分:3)
我知道这是超级老,但我偶然发现它寻找完全不同的东西,我想扔掉那里通常不建议使用浮点数(float 或十进制)对于货币,因为浮点数学舍入将总是导致计算中的小错误,这可能会导致长时间内出现非常大的差异。
相反,请根据您的喜好使用整数字段或字符串。将您的货币乘以将小数位移动到结尾并在存储时生成整数,然后在需要显示时将该小数位移回原来的位置。这基本上是银行(和大多数货币库)处理数据存储的方式,并将在以后为您节省大量麻烦。
我学到了很多,因为这不是一个常见的话题;也许这可以拯救别人做同样的事情。