PHP浮点数用==判断相等会出错,因IEEE 754双精度表示限制导致0.1+0.2=0.30000000000000004≠0.3;应改用abs($a - $b)
PHP浮点数直接用 == 判断相等会出错
因为
0.1 + 0.2在 PHP(以及几乎所有语言)里不等于0.3,而是0.30000000000000004。这不是 PHP 的 bug,是 IEEE 754 双精度浮点数的固有表示限制。常见错误现象:
if (0.1 + 0.2 == 0.3) { ... }永远不进分支;数据库查出来的float字段和 PHP 计算结果看似一样却比对失败。
- 永远别用
==或===直接比较两个浮点数是否“数学上相等”- 改用差值绝对值小于容忍误差(epsilon):
abs($a - $b)- 业务中常用容差要结合场景定,比如金额建议用
1e-2(分),科学计算可能需1e-15- 注意
bcadd()、bccomp()等 BCMath 函数不走浮点路径,但参数必须是字符串,传入0.1会先被转成浮点再截断——得写成'0.1'money_format() 和 number_format() 处理精度容易翻车
number_format()是字符串格式化函数,不改变数值本身;money_format()已在 PHP 8.0+ 被移除,且它底层仍依赖浮点运算,不能修复精度问题。典型误用:用
number_format(0.1 + 0.2, 1)得到'0.3'就以为“修好了”,其实中间计算仍是错的,后续再参与运算还会扩散误差。立即学习“PHP免费学习笔记(深入)”;
- 显示前格式化没问题,但所有中间计算必须避开浮点——该用整数(单位:分)就用整数,该用
BCMath就用BCMathnumber_format()的第二个参数是小数位数,但若原始值本身因浮点表示失真(如19.999999999999996),四舍五入可能出人意料- 替代方案:用
sprintf('%.2f', $val)行为类似,同样不解决根源;真正安全的是先用bcscale(2)+bcadd($a, $b)再格式化BCMath 函数传参必须是字符串,不是 float
这是最常踩的坑:
bcadd(0.1, 0.2, 1)和bcadd('0.1', '0.2', 1)结果完全不同。前者先把0.1转成浮点再转字符串,已经失真;后者才是精确路径。错误现象:
bcadd(0.1, 0.2, 1)返回'0.3'看似正常,但换成bcadd(0.1, 0.7, 1)可能返回'0.7'(因为0.7在二进制浮点中本就是近似值)。
- 所有 BCMath 函数(
bcadd、bcmul、bccomp等)只接受字符串参数,强制类型转换会立刻丢精度- 从数据库或用户输入拿到数字后,别用
(string)$float,而要用number_format($float, 10, '.', '')或正则提取有效数字字符(更稳妥)bcscale()设置全局小数位数,影响后续所有 BCMath 运算,但不会自动对齐输入精度——bcscale(2)下bcadd('1.234', '5.678', 2)仍按原精度算,最后才截断MySQL DECIMAL 字段和 PHP 浮点交互时精度悄悄丢失
PHP 的 MySQL 扩展(mysqli / PDO)默认把
DECIMAL字段作为字符串返回,但很多人用(float)强转或直接参与运算,瞬间回到浮点陷阱。常见场景:查出订单金额
99.99(数据库存的是DECIMAL(10,2)),PHP 里写成$total = (float)$row['amount'] + 0.01;,结果变成100.00000000000001。
- PDO 默认
PDO::ATTR_STRINGIFY_FETCHES = false,但某些配置或驱动版本下可能自动转 float,务必检查var_dump($row['amount'])类型- 最佳实践:保持 DECIMAL 字段始终以字符串流转,运算用 BCMath;或统一转成整数(乘 100)再算
- 如果必须用 float,至少用
round($val, 2)截断,但仅限展示或最终输出,绝不可用于中间计算事情说清了就结束。真正麻烦的从来不是“怎么调一个函数”,而是所有环节——输入、传输、存储、计算、输出——都得对齐精度策略,漏掉一环,前面全白干。
相关文章
如何在 PHP 中正确上传图片并保存到 MySQL 数据库
PHP 图片上传失败的常见原因与正确实现方法
如何正确统计循环中各商品数量总和(按品类分组并汇总)
如何正确统计循环中各商品数量总和(含分类汇总与总计)
如何在 PHP 循环中正确统计商品总数量(按品类分组累加)
相关标签:
本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
热门AI工具
相关专题
打开php文件步骤:1、选择文本编辑器;2、在选择的文本编辑器中,创建一个新的文件,并将其保存为.php文件;3、在创建的PHP文件中,编写PHP代码;4、要在本地计算机上运行PHP文件,需要设置一个服务器环境;5、安装服务器环境后,需要将PHP文件放入服务器目录中;6、一旦将PHP文件放入服务器目录中,就可以通过浏览器来运行它。
11624
2023.09.01
取出php数组的前几个元素的方法有使用array_slice()函数、使用array_splice()函数、使用循环遍历、使用array_slice()函数和array_values()函数等。本专题为大家提供php数组相关的文章、下载、课程内容,供大家免费下载体验。
6701
2023.10.11
php反序列化失败的解决办法检查序列化数据。检查类定义、检查错误日志、更新PHP版本和应用安全措施等。本专题为大家提供php反序列化相关的文章、下载、课程内容,供大家免费下载体验。
2175
2023.10.11
连接方法:1、通过mssql_系列函数;2、通过sqlsrv_系列函数;3、通过odbc方式连接;4、通过PDO方式;5、通过COM方式连接。想了解php怎么连接mssql数据库的详细内容,可以访问下面的文章。
4248
2023.10.23
php连接mssql数据库的方法有使用PHP的MSSQL扩展、使用PDO等。想了解更多php连接mssql数据库相关内容,可以阅读本专题下面的文章。
4974
2023.10.23
PHP出现乱码可以通过修改PHP文件头部的字符编码设置、检查PHP文件的编码格式、检查数据库连接设置和检查HTML页面的字符编码设置来解决。更多关于php乱码的问题详情请看本专题下面的文章。php中文网欢迎大家前来学习。
5617
2023.11.09
php文件在手机上打开需要在手机上搭建一个能够运行php的服务器环境,并将php文件上传到服务器上。再在手机上的浏览器中输入服务器的IP地址或域名,加上php文件的路径,即可打开php文件并查看其内容。更多关于php相关问题,详情请看本专题下面的文章。php中文网欢迎大家前来学习。
4402
2023.11.13
Vite项目打包部署专题汇集生产构建、产物预览、输出目录、资源路径、Nginx与GitHub Pages部署及常见白屏和路由404问题的已审核文章,帮助读者完成上线流程。
20
2026.10.28
热门下载
相关下载
精品课程
最新文章












