PHP和Python浮点数精度问题

浮点数精度问题

下面的代码都是PHP代码,Python的浮点数精度问题可以使用下面同样的方法解决

$i = 0.58;
echo intval($i*100);
// 输出结果 57

:pen: what? 为啥输出了57
针对这个问题,逛了鸟哥的博客。(PHP浮点数的一个常见问题的解答
主要需要理解的就是在计算机中浮点数转成二进制时是无限长的值。

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

浮点数, 以64位的长度(双精度)为例, 会采用1位符号位(E), 11指数位(Q), 52位尾数(M)表示(一共64位).
符号位:最高位表示数据的正负,0表示正数,1表示负数。
指数位:表示数据以2为底的幂,指数采用偏移码表示
尾数:表示数据小数点后的有效数字。
而两者的二进制, 如果只是通过这52位计算的话,分别是:

0.58 -> 0.57999999999999996
0.57 -> 0.56999999999999995

当使用0.58*100的时候实际上是0.57999999999999996*100=57.999999999999996,再使用intval()自然就是57了。
看似有穷的小数在计算机的二进制表示里实际上是无穷的。

解决方案

使用round()函数

$i = 0.58;
echo round($i*100);
// 输出结果 58
点赞

发表评论

电子邮件地址不会被公开。必填项已用 * 标注