zoukankan      html  css  js  c++  java
  • PHP 浮点数高精度运算

    现在一家电商公司入职,做的是数据分析。

    用php经常会于一些计算报表。难免会遇到浮点数运算的 坑。

    
    
    $f = 0.58;
    var_dump(intval($f * 100)); //为啥输出57
    我们期待的结果应该是 0.58

    结果是有问题的。

    我们来看看php官方如何解释的:

    PHP 通常使用 IEEE 754 双精度格式,则由于取整而导致的最大相对误差为 1.11e-16。

    非基本数学运算可能会给出更大误差,并且要考虑到进行复合运算时的误差传递。

    永远不要相信浮点数结果精确到了最后一位,也永远不要比较两个浮点数是否相等。

    如果确实需要更高的精度,应该使用 任意精度数学函数

    任意精度数学函数

    官方手册:http://php.net/manual/zh/book.bc.php

    大家在使用前,请先确认是否已安装 bcmath。

    <?php
    echo '任意精度函数'. "<br>";
    //
    $a = 0.1;
    $b = 0.7;
    $c = intval(bcadd($a, $b, 1) * 10);
    echo $c."<br>";
    //输出:8
    
    
    //减
    $a = 100;
    $b = 99.98;
    $c = bcsub($a, $b, 2);
    echo $c."<br>";
    //输出:0.02
    
    
    //乘
    $a = 0.58;
    $b = 100;
    $c = intval(bcmul($a, $b));
    echo $c."<br>";
    //输出:58
    
    
    //除
    $a = 0.7;
    $b = 0.1;
    $c = intval(bcdiv($a, $b));
    echo $c."<br>";
    //输出:7

    bcmath 提供了以下方法:

    bcadd — 将两个高精度数字相加

    bccomp — 比较两个高精度数字,返回-1, 0, 1

    bcdiv — 将两个高精度数字相除

    bcmod — 求高精度数字余数

    bcmul — 将两个高精度数字相乘

    bcpow — 求高精度数字乘方

    bcpowmod — 求高精度数字乘方求模,数论里非常常用

    bcscale — 配置默认小数点位数,相当于就是Linux bc中的”scale=”

    bcsqrt — 求高精度数字平方根

    bcsub — 将两个高精度数字相减

    常用数值处理方案

    舍去法取整(向下取整)

    echo '向下取整'. "<br>";
    echo floor(1.1);
    //输出:1
    echo floor(4.8);
    //输出:4

    进一法取整(向上取整)

    echo '进一法取整(向上取整)'. "<br>";
    echo ceil(1.1);
    //输出:2
    echo ceil(4.8);
    //输出:5

    普通四舍五入法

    echo '普通四舍五入'. "<br>";
    echo round(5.1);
    echo number_format(5.1,0);
    //输出:5
    echo round(8.8);
    echo number_format(8.8,0);
    //输出:9

    数值格式化(千位分组)

    应用于金额的展示,比如我们经常会看的银行卡余额。

     echo number_format(10000000,2,'.',',');
    //输出 10,000,000.00

    在 MySQL 中,表字段有单精度浮点数(float)和双精度浮点数(double)。

    浮点数存在误差,当我们使用精度敏感的数据时,应该使用定点数(decimal)进行存储。

    Repeat Posts

    鸟哥:http://www.laruence.com/2013/03/26/2884.html

    您的资助是我最大的动力!
    金额随意,欢迎来赏!

    如果,您认为阅读这篇博客让您有些收获,不妨点击一下右下角的推荐按钮。
    如果,您希望更容易地发现我的新博客,不妨点击一下绿色通道的关注我

    如果,想给予我更多的鼓励,求打

    因为,我的写作热情也离不开您的肯定支持,感谢您的阅读!

  • 相关阅读:
    085 Maximal Rectangle 最大矩形
    084 Largest Rectangle in Histogram 柱状图中最大的矩形
    083 Remove Duplicates from Sorted List 有序链表中删除重复的结点
    082 Remove Duplicates from Sorted List II 有序的链表删除重复的结点 II
    081 Search in Rotated Sorted Array II 搜索旋转排序数组 ||
    080 Remove Duplicates from Sorted Array II 从排序阵列中删除重复 II
    079 Word Search 单词搜索
    078 Subsets 子集
    bzoj2326: [HNOI2011]数学作业
    bzoj2152: 聪聪可可
  • 原文地址:https://www.cnblogs.com/GreenForestQuan/p/10619574.html
Copyright © 2011-2022 走看看