千家信息网

PHP浮点数精度问题总结

发表于:2025-02-23 作者:千家信息网编辑
千家信息网最后更新 2025年02月23日,这篇文章主要介绍"PHP浮点数精度问题总结",在日常操作中,相信很多人在PHP浮点数精度问题总结问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"PHP浮点数精度问题总结"
千家信息网最后更新 2025年02月23日PHP浮点数精度问题总结

这篇文章主要介绍"PHP浮点数精度问题总结",在日常操作中,相信很多人在PHP浮点数精度问题总结问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"PHP浮点数精度问题总结"的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

一、PHP浮点数精度损失问题

先看下面这段代码:

$f = 0.57;
echo intval($f * 100); //56

结果可能有点出乎你的意外,PHP遵循IEEE 754双精度:

浮点数, 以64位的双精度, 采用1位符号位(E), 11指数位(Q), 52位尾数(M)表示(一共64位).
符号位:最高位表示数据的正负,0表示正数,1表示负数。
指数位:表示数据以2为底的幂,指数采用偏移码表示
尾数:表示数据小数点后的有效数字.

再来看看小数用二进制怎么表示:

乘2取整,顺序排列,即将小数部分乘以2,然后取整数部分,剩下的小数部分继续乘以2,然后取整数部分,剩下的小数部分又乘以2,一直取到小数部分,但是像0.57这样的小数像这样一直乘下去,小数部分不可能为0.有效位的小数用二进制表示却是无穷的。

0.57的二进制表示基本上(52位)是: 0010001111010111000010100011110101110000101000111101

如果只有52位的话,0.57 =》 0.56999999999999995

不难看出上面意外的结果了吧。

二、PHP浮点数的精度问题

先看问题:

复制代码 代码如下:


$f = 0.58;
var_dump(intval($f * 100)); //为啥输出57

我相信有很多的同学有过这样的疑问。

具体原理可阅读"鸟哥"的一篇文章,那里有详细的解说:PHP浮点数的一个常见问题的解答

那么如何避免这种问题呢?
办法有很多,这里列举两个:
1. sprintf

复制代码 代码如下:


substr(sprintf("%.10f", ($a/ $b)), 0, -7);


2. round (注意会进行四舍五入)

复制代码 代码如下:


round($a/$b, 3);


或者你有更好的办法,也可以了留言告诉我。

三、PHP浮点数的一个常见问题的解答

关于PHP的浮点数, 我之前写过一篇文章: 关于PHP浮点数你应该知道的(All 'bogus' about the float in PHP)

不过, 我当时遗漏了一点, 也就是对于如下的这个常见问题的回答:

复制代码 代码如下:


$f = 0.58;
var_dump(intval($f * 100)); //为啥输出57
?>


为啥输出是57啊? PHP的bug么?

我相信有很多的同学有过这样的疑问, 因为光问我类似问题的人就很多, 更不用说bugs.php.net上经常有人问…

要搞明白这个原因, 首先我们要知道浮点数的表示(IEEE 754):

浮点数, 以64位的长度(双精度)为例, 会采用1位符号位(E), 11指数位(Q), 52位尾数(M)表示(一共64位).

符号位:最高位表示数据的正负,0表示正数,1表示负数。

指数位:表示数据以2为底的幂,指数采用偏移码表示

尾数:表示数据小数点后的有效数字.

这里的关键点就在于, 小数在二进制的表示, 关于小数如何用二进制表示, 大家可以百度一下, 我这里就不再赘述, 我们关键的要了解, 0.58 对于二进制表示来说, 是无限长的值(下面的数字省掉了隐含的1)..

0.58的二进制表示基本上(52位)是: 0010100011110101110000101000111101011100001010001111
0.57的二进制表示基本上(52位)是: 0010001111010111000010100011110101110000101000111101
而两者的二进制, 如果只是通过这52位计算的话,分别是:

复制代码 代码如下:


0.58 -> 0.57999999999999996
0.57 -> 0.56999999999999995


至于0.58 * 100的具体浮点数乘法, 我们不考虑那么细, 有兴趣的可以看(Floating point), 我们就模糊的以心算来看… 0.58 * 100 = 57.999999999

那你intval一下, 自然就是57了….

到此,关于"PHP浮点数精度问题总结"的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!

点数 问题 小数 代码 精度 二进制 部分 数据 尾数 数位 符号 学习 有效 常见 常见问题 数字 篇文章 解答 输出 最高 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 王者服务器会在晚上关闭吗 神经网络技术常用算法 帆软查询不同数据库 数据库备份占内存么 我的世界高级太阳能服务器刷不了 电竞酒店的服务器是怎么装的 深圳麦迅互联网科技有限公司 跟村民有关网络安全知识 人脸区分识别软件开发 单片机能否用PLC软件开发 pve服务器 部落 软件开发过程中的原型模型 金网络安全插画 好玩视频软件开发 多措并举提高网络安全水平 三级网络技术容易考吗 合肥软件开发公司有哪些 笔记本做数据库6 高中信息技术数据库的管理 物理服务器视频教程 武汉凡提网络技术有限公司天眼查 协同软件开发哪家好公司 如何清理dell服务器 软件开发引擎使用 西城区网络营销软件开发反馈 论文查重的数据库有哪些论文 沈阳定制化国产服务器 ui设计的专业软件开发 数元网络技术有限公司 长沙三维家网络技术有限公司
0