2014-10-02 353 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

相關問題