2009-11-26 51 views
4

我正在创建一个财务应用程序,似乎我在sqlite中的浮动工具正在浮动。有时4.0会是4.000009,6.0会是6.00006,类似的事情。我怎样才能使这些更精确,不会影响我的财务计算?如何处理在Python SQLite中进行财务计算的浮动类型舍入错误?

值来自Python如果重要。不确定哪个区域的数字是来自哪里。

+0

http://docs.python.org/tutorial/floatingpoint。html – bernie 2009-11-26 03:08:39

+0

http://docs.sun.com/source/806-3568/ncg_goldberg.html – Ken 2009-11-26 03:34:59

+0

请生成一个最简单的例子。 – 2015-11-20 20:22:40

回答

3

这是使用SQLite,因为它不具备货币型的通病。
正如S.Mark所说,您可以使用Decimal表示库。然而,SQLite 3只支持二进制浮点数(sqlite类型为REAL),因此您必须将十进制编码的浮点数存储为TEXT或BLOB或将其转换为REAL(但那时您会回到64位二进制浮点数)
因此,请考虑您需要表示的数字范围以及是否需要能够从数据库内执行计算。

您最好使用支持NUMERIC类型的不同DB,例如, MYSqlPostgreSQLFirebird

+0

是的,你可能是正确的,但SQLite是如此的简单和灵活 – Recursion 2009-11-26 05:14:50

4

看到,因为这是一个财务应用,如果你只需要计算高达2个或3位小数,您可以在内部存储所有的数据作为整数,只将它们转换为浮动用于演示目的。

E.g.

6.00 -> 600 
4.35 -> 435 
+0

我认为这是可怕的建议,*浮动* 600美元将四舍五入到600.01美元。 *双倍*向您购买了一些更有意义的数字,但仍不是正确的做法 - 如果此代码最终在财务软件中用于数十亿美元的交易,该怎么办? – 2009-11-26 04:17:37

+0

这就是为什么我说你可以用整数算术来代替(例如4003,实际上是4.003,在整数算术中会有精确的表示),除非你的意思是别的吗?例如。请详细说明。 – 2009-11-26 05:19:37

+0

因为国际转换率在点之后有两位数字以上,所以不是一个好主意。像1欧元是6,55956法郎。 – 2009-11-26 23:48:49

0

您必须使用十进制数字。 十进制数可以完全表示。

在十进制浮点数中,0.1 + 0.1 + 0.1 - 0.3正好等于零。在二进制浮点,结果是5.5511151231257827e-017.

所以,只要尝试十进制:

import decimal 
1

大多数人可能会为此使用Decimal,但是如果这没有映射到数据库类型上,则可能会导致性能下降。

如果性能很重要,您可能需要考虑使用整数来表示合适的货币单位 - 通常分或十分之一美分是可以的。

应该有关于如何在各种情况下舍入金额的商业规则,并且您应该对每种方案进行测试。

1

使用Decimal来操作你的数字,然后使用pickle来保存它并从SQLite中将它作为文本加载,因为它不处理数字类型。

最后,使用unitestdoctest,对于财务操作,您希望确保所有代码在任何情况下都能做到它应该做的事情。您无法像修改社交网络那样修复错误...