對高精度數字的處理。給各位安利一個坑。我相信很多人會遇到過。

yema發表於2018-11-09

前言

大家好,本章開頭先給大家說一個我畢業工作遇到的第一個坑。
公司自主開發了一個商城小程式,第一階段大概用時2個月。我負責後端邏輯實現。我們公司不加班。
那天主管有事,半路把購買支付的邏輯程式碼半路扔給了我。還好,不是很難,微信文件一刷,很速度的完成了支付回撥功能的邏輯處理。
就這樣過了一段時間。
一天早上主管測試購買商品。因為是測試嘛,商品都是幾分的,主管瀟灑的清空了購物車,一共7分錢。支付完成後,尷尬了,這支付回撥怎麼沒回來那,主管不信邪,這邏輯程式碼也不是我一個人寫的,速度的又購買了一批6分的錢的貨,支付回撥又通了。這下輪到我倆懵逼了。日誌一打,好啊,這7分錢到微信那裡就變成0.699999999999999了。我這程式碼一擼下來,這價格相加的精度丟失了啊。做過微信支付的都知道微信會驗證付款金額和下單的金額是否一致的。這就出個坑來了。

結果

由於表事先存金額並沒有按照分來存,程式碼邏輯基本完成的情況下,我們選擇使用 PHP 內建的 BCMath 庫來進行浮點數的計算。

!!BCMath 函式需要開啟擴充套件才可以使用,傳入的引數會被轉為字串進行操作,返回值依舊為字串。可以使用 function_defined('bcadd') 來檢查某一個函式是否被定義

bcadd( $numb1,$numb2,2 )
將2個高精度數字相加,保留2位小數

bccomp( $numb1,$numb2,2 )
比較2個高精度數字,小數點後2位。
如果引數1大於引數2,返回1
如果小於,返回-1
如果等於,返回0

bcdiv(...)
將2個高精度數字相除

bcmod(...)
求高精度數字餘數

bcmul(...)
對2個高精度數字相乘

bcpow(...)
求高精度數字乘方

bcpowmod(...)
求高精度數字乘方求模,數論裡非常常用

bcsqrt(...)
求高精度數字平方根

bcsub(...)

將兩個高精度數字相減

除了使用 BCMath 函式 還可以使用 GMP 函式,同樣需要開啟擴充套件,還有 PECL 的 big_init 庫,GMP 和 big_init 的處理速度相當,但是都要比 BCMath 處理速度要快,但是使用起來 BCMath 更加簡便和簡單。

為什麼我可以這麼的菜?

相關文章