资讯专栏INFORMATION COLUMN

PHP处理数学精度

chaos_G / 1666人阅读

摘要:后来我看了下,确实有这么一个扩展库,处理任意精度数字,对于任意精度的数学,提供了支持用字符串表示的任意大小和精度的数字的二进制计算。

用编程语言做计算,很多时候浮点数精度都是困扰过我的问题,即便是刚学PHP的新手也会在群里问为什么我的计算结果明显不对,而我们总是老态龙钟的丢出一句浮点数计算都存在精度问题,并没有提出过什么实质性的改善。比如下面的计算 0.57*100

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

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

看到结果其实我们已经想到了,很多时候我们忽略精度问题,一定意义上是因为我们没有对计算结果进行类型转换,巧妙的得到了更好的结果值。但是总会有(细心)的开发者会自作聪明的对结果进行指定,恰恰得到了相反的效果。这也是为什么我一直没有仔细想过这个问题的原因,按动态解释性语言的特性,变量都是在运行时才最终确定的,所以不要刻意去转换类型,即便你很确认变量就应该是这个样子的。

我记得在刚学PHP的时候,偶然间看到网络上高洛峰的一个视频,其间有一句话就说以后你们在PHP编程中,会遇到很多一时半会解释不清楚的问题,那时候你们首先想到的应该是这门语言的特性--解释性,自然你就会慢慢理解了。

后来我看了下,PHP确实有这么一个扩展库,BCMath处理任意精度数字,对于任意精度的数学,PHP提供了支持用字符串表示的任意大小和精度的数字的二进制计算。自 PHP 4.0.4,libbcmath 随同 PHP 一起发布,该扩展不需要任何外部的库。官方文档提供的函数有如下这些:

bcadd — 2个任意精度数字的加法计算

bccomp — 比较两个任意精度的数字

bcdiv — 2个任意精度的数字除法计算

bcmod — 对一个任意精度数字取模

bcmul — 2个任意精度数字乘法计算

bcpow — 任意精度数字的乘方

bcpowmod — Raise an arbitrary precision number to another, reduced by a specified modulus

bcscale — 设置所有bc数学函数的默认小数点保留位数

bcsqrt — 任意精度数字的二次方根

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一般,而表现的很不尊重别人。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/25810.html

相关文章

  • 系统的讲解 - PHP 浮点数高精度运算

    摘要:浮点数类型包括单精度浮点数和双精度浮点数。小结通过浮点数精度的问题,了解到浮点数的小数用二进制的表示。以后,在使用浮点数运算的时候,一定要慎之又慎,细节决定成败。 概述 记录下,工作中遇到的坑 ... 关于 PHP 浮点数运算,特别是金融行业、电子商务订单管理、数据报表等相关业务,利用浮点数进行加减乘除时,稍不留神运算结果就会出现偏差,轻则损失几十万,重则会有信誉损失,甚至吃上官司,我...

    makeFoxPlay 评论0 收藏0
  • PHP变量类型

    摘要:获取变量的类型,使用函数。要检验某个类型,可以使用函数,如是在整形是在浮点型是在字符串如果需要将一个变量强制转换为某类型,可以对其使用强制转换或者函数。自起,此限制仅对包含变量时有效。 简介 PHP支持9种原始数据类型。 4种标量类型: boolean布尔型 integer 整形 float 浮点型(也称作double) string 字符串 3种复合类型: array...

    selfimpr 评论0 收藏0
  • 浮点数那些事儿

    摘要:说起浮点数,大家都是又恨又爱的。当小数不为时,浮点数的值为,即不是一个数。所以,整个浮点数的二进制表示就是。最后其实,浮点数有很多坑。因此,我们在使用浮点数的时候,一定要小心。还有,涉及到金额计算的时候,一定不能使用浮点数。 本文为作者自己的总结的,由于作者的水平限制,难免会有错误,欢迎大家指正,感激不尽。 说起浮点数,大家都是又恨又爱的。爱呢,是因为,只有它可以方便地使用小数;恨呢,...

    Honwhy 评论0 收藏0
  • 浮点数那些事儿

    摘要:说起浮点数,大家都是又恨又爱的。当小数不为时,浮点数的值为,即不是一个数。所以,整个浮点数的二进制表示就是。最后其实,浮点数有很多坑。因此,我们在使用浮点数的时候,一定要小心。还有,涉及到金额计算的时候,一定不能使用浮点数。 本文为作者自己的总结的,由于作者的水平限制,难免会有错误,欢迎大家指正,感激不尽。 说起浮点数,大家都是又恨又爱的。爱呢,是因为,只有它可以方便地使用小数;恨呢,...

    YFan 评论0 收藏0

发表评论

0条评论

chaos_G

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<