一、媒介
如果用php的+-/打算浮点数的时候,可能会碰着一些打算结果缺点的问题,比如echo intval( 0.58100 );会打印57,而不是58,这个实在是打算机底层二进制无法精确表示浮点数的一个bug,是跨措辞的,比如说python也会碰着这个问题。
例子:

二、浮点数表示规则
为啥输出是57? 首先我们要知道浮点数的表示(IEEE 754):
浮点数, 以64位的长度(双精度)为例, 会采取1位符号位(E), 11指数位(Q), 52位尾数(M)表示(一共64位).
符号位:最高位表示数据的正负,0表示正数,1表示负数。
指数位:表示数据以2为底的幂,指数采取偏移码表示
尾数:表示数据小数点后的有效数字.
三、浮点数二进制表示办法
这里的关键点就在于, 小数在二进制的表示办法:
将该数字乘以2,取出整数部分作为二进制表示的第1位;然后再将小数部分乘以2,将得到的整数部分作为二进制表示的第2位;以此类推,直到小数部分为0。
以0.625为例:
0.625 2 = 1.25 —————- 1
0.25 2 = 0.5 —————— 0
0.5 2 = 1.0 ——————- 1
小数部分为0,停滞运算,0.625用二进制表示便是 0.101
以0.58为例:
0.58 2 = 1.16 ——————- 1
0.16 2 = 0.32 ——————- 0
0.32 2 = 0.64 ——————- 0
0.64 2 = 1.28 ——————- 1
0.28 2 = 0.56 ——————- 0
0.56 2 = 1.12 ——————- 1
0.12 2 = 0.24 ——————- 0
0.24 2 = 0.48 ——————- 0
.....
小数部分涌现循环,无法停滞,但是由于尾数最长只有52位,以是无法准确的表示0.57这个数,在从二进制转换回十进制时便是0.579999999... 那你10之后intval一下, 自然便是57了….
四、结语
可见这个问题的关键点便是: “你看似有穷的小数, 在打算机的二进制表示里却是无穷的” so, 不要再以为这是PHP的bug了, 这便是这样的…..