PHP處理數學精度

用編程語言作計算,不少時候浮點數精度都是困擾過個人問題,即使是剛學PHP的新手也會在羣裏問爲何個人計算結果明顯不對,而咱們老是老態龍鍾的丟出一句浮點數計算都存在精度問題,並無提出過什麼實質性的改善。好比下面的計算 0.57*100php

zhgxun-pro:~ zhgxun$ php -a
Interactive shell

php > echo intval(0.57*100);
56
php > echo 0.57*100;
57
php >

看到結果其實咱們已經想到了,不少時候咱們忽略精度問題,必定意義上是由於咱們沒有對計算結果進行類型轉換,巧妙的獲得了更好的結果值。可是總會有(細心)的開發者會自做聰明的對結果進行指定,偏偏獲得了相反的效果。這也是爲何我一直沒有仔細想過這個問題的緣由,按動態解釋性語言的特性,變量都是在運行時才最終肯定的,因此不要刻意去轉換類型,即使你很確認變量就應該是這個樣子的。shell

我記得在剛學PHP的時候,偶然間看到網絡上高洛峯的一個視頻,其間有一句話就說之後大家在PHP編程中,會遇到不少一時半會解釋不清楚的問題,那時候大家首先想到的應該是這門語言的特性--解釋性,天然你就會慢慢理解了。編程

後來我看了下,PHP確實有這麼一個擴展庫,BCMath處理任意精度數字,對於任意精度的數學,PHP提供了支持用字符串表示的任意大小和精度的數字的二進制計算。自 PHP 4.0.4,libbcmath 隨同 PHP 一塊兒發佈,該擴展不須要任何外部的庫。官方文檔提供的函數有以下這些:bash

  1. bcadd — 2個任意精度數字的加法計算
  2. bccomp — 比較兩個任意精度的數字
  3. bcdiv — 2個任意精度的數字除法計算
  4. bcmod — 對一個任意精度數字取模
  5. bcmul — 2個任意精度數字乘法計算
  6. bcpow — 任意精度數字的乘方
  7. bcpowmod — Raise an arbitrary precision number to another, reduced by a specified modulus
  8. bcscale — 設置全部bc數學函數的默認小數點保留位數
  9. bcsqrt — 任意精度數字的二次方根
  10. bcsub — 2個任意精度數字的減法

若是不是設計太複雜的運算,只須要其中的加減乘除既能夠作到高精度的數學處理。網絡

class Test extends Command
{
    protected $signature = 'test';
    protected $description = '測試樣例';
    
    public function handle()
    {
        // 使用BCMath進行高精度運算
        $a = 0.57;
        $b = 100;

        echo intval($a * $b) . PHP_EOL;
        echo $a * $b . PHP_EOL;
        echo bcmul($a, $b) . PHP_EOL;

        $c = 1;
        $d = 3;
        echo intval($c / $d) . PHP_EOL;
        echo $c / $d . PHP_EOL;
        echo bcdiv($c, $d, 6) . PHP_EOL;
    }
}

執行結果:編程語言

zhgxun-pro:ankerbox_finance zhgxun$ php artisan test
56
57
57
0
0.33333333333333
0.333333
zhgxun-pro:ankerbox_finance zhgxun$

結果跟說明的同樣,你只要不要刻意去作數字精度的轉換計算,PHP其實表現的很良好的,並無你們說的那麼可怕,以爲這門語言有太多的問題。只是可能當咱們知道PHP有專門的函數來處理這個問題時,會不禁自主的也以爲精度問題就應該這麼作纔對,若是對方碰巧不知道這其中的問題,就以爲對方很low通常,而表現的很不尊重別人。函數

相關文章
相關標籤/搜索