2013-10-02 81 views
0

我有一個項目,存儲在bigint列在數據庫中的錢(存儲在美分)。我打算重寫這個東西來代替使用BCMATH。我不介意整數,但他們給我一些存儲在美分中的可怕四捨五入錯誤事件,我懷疑我可能在BCMATH中有相同的舍入錯誤。問題出現在的情況下,想在這個僞代碼:PHP的錢計算精度

$price = $some_price_in_cents * $store_price_increase; // second value is a float for final price calculation, so the result might have fractions of a cent 
$price_total = $price * $qty; 
$discount = // some discount in cents (might have fractions of a cent) 
$discount *= $qty; 
$discounted_price = $price_total - $discount; 

當插入到數據庫中,我做輪()在仙的所有值。現在,我有說,一個記錄:

total price = 12134 
discount = 460 
discounted price = 11675 

現在,如果我做12134 - 460 ......我明明得到11674,而不是11675. 我也懷疑,如果我改變了事情的計算方法(如:我會得到不同的結果。

我會用BCMATH得到這種行爲嗎?結果會取決於數學運算的順序嗎?我如何正確計算上述使用BCMATH並將其存儲在數據庫中(假設需要2個小數位)?

+1

我建議使用DECIMAL數據類型來存儲錢。 –

+0

除非您溢出整數(在32位上爲> = 2^31或在64位上爲2^63),並且除非正在執行分割,否則不能使用整數算術產生錯誤。 'round()'實際上[返回一個浮點數](http://php.net/manual/fr/function.round.php),我懷疑你實際上在某些時候不知道使用浮點數。我個人將所有金額存儲在數據庫中,使用整數列;這是非常安全的,並且適用於多種貨幣('DECIMAL'具有固定的精度)。將貨幣作爲整數(以次要單位)與貨幣代碼一起存儲可解決問題。 – Benjamin

+0

關於你的錢操作,我建議你使用一個合適的[PHP Money庫](https://github.com/brick/money)(免責聲明:我創作了這個)。這款產品使用純粹的PHP,GMP或BCMath,基於可用的內容,並確保對任何規模的資金進行安全計算。另外,您可以將貨幣轉換爲整數並將其轉換爲整數,以將其安全地存儲在數據庫中。 – Benjamin

回答

1

我相信這是你需要的。請注意,bcmath需要字符串。數字2是指定你需要多少小數。

$price = bcmul($some_price_in_cents, $store_price_increase, 2); 
$price_total = bcmul($price, $qty, 2); 
$discount = bcmul($qty, "discount amount", 2); 
$discounted_price = bcsub($price_total, $discount, 2);