2014-10-02 32 views
2

据我所知,由于舍入误差问题,货币值应作为整数存储和处理。这对我有意义,我明白了(我认为)。税率是否需要存储为整数?

但税率呢?是否有任何理由将税率(不是税额,税率,如6.5或8.125)存储为整数而不是小数?

如果我确实将整个税率存储为整数,那么如何将税率应用于交易中的美元金额?如果我对6.5%的税率做10000 * 1.065($ 100.00 * 1.065),将6.5%存储在数据库中的好处是6500而不是6.500?我不认为一次乘以或乘以100是易受舍入误差的影响。

我存储税率如何?

+0

浮点算法出现问题([这里是一个解释](https://docs.python.org/2/tutorial/floatingpoint.html))。如果您将税率存储为* decimal *而非float,并确保公式的结果是* decimal * precision值,而不是float,则我不知道会有任何舍入错误。你在做什么环境?更多信息和用例/例子和某人可能能够提供更多指导。 – 2014-10-02 18:38:34

回答

2

首先,这不是你不应该使用小数。这是你不应该使用浮点,你想有一个确切的价值。并非所有的小数点都是浮点数;请参阅C#中的十进制数据类型或Java中的java.math.BigDecimal。

其次,10的幂特别容易受到奇怪的浮点问题的影响,因为实现浮点的方式会导致无限次地重复10进制除法。请参阅this question。这里有一个简单的例子:

groovy:000> f = 0.1F // make a floating point number 
===> 0.1 
groovy:000> f * 100 
===> 10.000000149011612 

发生这种情况是因为0.1的表示是重复的十进制数被截断。在这里,REPL说谎,f中真正的不是0.1,它是0.100000001490116119384765625。

你可以这一轮去上,there's an argument for doing that

要解决此问题,您需要提供适当的四舍五入。有了钱,这很容易,因为你知道有多少小数点是合适的,除非你有70万亿美元,否则你不会得到足够大的舍入误差,你不能纠正它。

但使用BigDecimals的:

groovy:000> d = new BigDecimal("0.1") 
===> 0.1 
groovy:000> d * 100 
===> 10.0 

让你清楚知道什么号码,你有使用定点小数。如果你的语言没有固定的小数(如Javascript),you may have to fall back on integers

+0

明白了。所以说,对于货币,我总是希望通过定点数乘以定点数? – 2014-10-02 18:46:14

+0

这是一个完全独立的问题,但我现在对我为什么看到很多人主张将货币价值存储为“美分”而非美元数量感到困惑,例如, 10000而不是100.00。 – 2014-10-02 18:47:35

+0

@Jason:差不多。 http://vanillajava.blogspot.com/2011/08/double-your-money-again.html中有一篇有趣的文章反过来论证。但你必须知道你在做什么。 – 2014-10-02 18:47:45

相关问题