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通常,而表现的很不尊重别人。函数

相关文章
相关标签/搜索