php处理浮点数、精度运算、数字处理

本文主要探讨了PHP中浮点数运算存在的精度问题,特别是在金融和电商场景下需要注意的细节。错误的浮点数运算可能导致结果偏差,如加法、减法、乘法和除法的例子所示。为了解决这个问题,文章推荐使用bcmath库来进行任意精度的数学运算,如bcadd、bcsub、bcmul和bcpow等函数。此外,还介绍了常用的数值处理方法,包括舍入和银行家舍入法,以及数值格式化的示例,如number_format函数用于金额展示的千位分组。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本篇文章给大家介绍php处理浮点数、精度运算、数字处理等。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。
前言

  1. php浮点类型数字进行运算 稍微不留神就会出现偏差 特别是金融行业,电子商户订单,商城类项目。

  2. 浮点数的精度有限。尽管取决于系统,PHP 通常使用 IEEE 754 双精度格式,则由于取整而导致的最大相对误差为 1.11e-16。非基本数学运算可能会给出更大误差,并且要考虑到进行复合运算时的误差传递。永远不要相信浮点数结果精确到了最后一位,也永远不要比较两个浮点数是否相等。如果确实需要更高的精度,应该使用任意精度数学函数 或者 gmp 函数。

一 . 运算
错误

//加
$a = 0.1; $b = 0.7; $c = intval(($a + $b) * 10); echo $c."
"; //输出:7
    //减
$a = 100; $b = 99.98; $c = $a - $b; echo $c."
"; //输出:0.019999999999996
    //乘
$a = 0.58; $b = 100; $c = intval($a * $b); echo $c."
"; //输出:57
    //除
$a = 0.7; $b = 0.1; $c = intval($a / $b); echo $c."
"; //输出:6

正确

  1. 对于任意精度的数学,PHP 提供了支持用字符串表示的任意大小和精度的数字的二进制计算。
  2. 官方手册:php.net/manual/zh/book.bc.php
  3. 大家在使用前,请先确认是否已安装 bcmath。
//加
$a = 0.1; $b = 0.7; $c = intval(bcadd($a, $b, 1) * 10); echo $c."
"; //输出:8
    //减
$a = 100; $b = 99.98; $c = bcsub($a, $b, 2); echo $c."
"; //输出:0.02
    //乘
$a = 0.58; $b = 100; $c = intval(bcmul($a, $b)); echo $c."
"; //输出:58
    //除
$a = 0.7; $b = 0.1; $c = intval(bcp($a, $b)); echo $c."
"; //输出:7

除了加减乘除,bcmath 还提供了以下方法:

  1. bccomp 比较两个任意精度的数字
  2. bcmod 对一个任意精度数字取模
  3. bcpow 任意精度数字的乘方
  4. bcpowmod 高精度数字乘方求模
  5. bcscale 设置所有bc数学函数的默认小数点保留位数
  6. bcsqrt 任意精度数字的二次方根

二 . 常用数值处理方案

舍去法取整(向下取整)
echo floor(5.1);
//输出:5
echo floor(8.8);
//输出:8
进一法取整(向上取整)
echo ceil(5.1);
//输出:6
echo ceil(8.8);
//输出:9
普通四舍五入法
echo round(5.1);
//输出:5
echo round(8.8);
//输出:9
//保留两位小数并且进行四舍五入
echo round(5.123, 2);
//输出:5.12
echo round(8.888, 2);
//输出:8.89
//保留两位小数并且不进行四舍五入
echo substr(round(5.12345, 3), 0, -1);
//输出:5.12
echo substr(round(8.88888, 3), 0, -1);
//输出:8.88

银行家舍入法

  1. 四舍六入五考虑,五后非空就进一,五后为空看奇偶,五前为偶应舍去,五前为奇要进一。
  2. 保留两位小数 例:
1.2849 = 1.28 -> 四舍

1.2866 = 1.29 -> 六入

1.2851 = 1.29 -> 五后非空就进一

1.2850 = 1.28 -> 五后为空看奇偶,五前为偶应舍去

1.2750 = 1.28 -> 五后为空看奇偶,五前为奇要进一

数值格式化(千位分组)

  1. 应用于金额的展示,比如我们经常会看的银行卡余额。
echo number_format('10000.98', 2, '.', ','); //输出:10,000.98

    echo number_format('340888999', 2, '.', ',');

//输出:340,888,999.00
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值