浮点型(float或double)表示的变量属于实数的集合。在C语言里,float和double是不同的类型,但在PHP语言里,两者没有区分,都是float类型。PHP的浮点数采用IEEE二进制浮点数算术标准(IEEE 754),通常最大值是1.8e308并具有14位十进制数字的精度(64位IEEE格式)。
浮点数的表示方法一般有两种:使用小数点和科学计数法,如表2-4所示。
表2-4 浮点数的表示方法
题目描述: 比较两个浮点数是否相等。
程序代码如下:(源码文件:ch02/float_compare.php)
1 <?php 2 var_dump(0.3 == 3e-1);//bool(true) 3 var_dump(0.3 == 0.1 + 0.2);//bool(false) 4 var_dump(1100.80 * 100 == 110080);//bool(true) 5 var_dump(1100.85 * 100 == 110085);//bool(false) 6 ?>
为什么第3行和第5行的结果是false呢?原因在于浮点数在计算机内部的表示。例如IEEE 754标准 对64位的双精度数字的表示如表2-5所示。
表2-5 IEEE 754标准对64位的双精度数字的表示
双精度数所能表示的有效数字位数为52,由于有效数字最左位一定是1,所以共有53位。
log 2 53 ≈15.95
所以,一般来说,对于64位的双精度数字,只有前15位的有效数字是有意义的,这保证了最大误差一般不大于10 -16 。
例如:
<?php var_dump(0.3 - (0.1+0.2)); //Output float(-5.5511151231258E-17) ?>
需要注意,任何抛弃精度谈浮点数的比较都是无意义的。
题目描述: 证明0.999…=1。
方法1: 已知 ,将两端同时乘以3,则得到1=0.999…。
方法2: 0.999…可表示为以下等比数列之和:
0.9,0.09,0.009,…
而等比数列之和为
由此得证。
以上不是数学上严谨的证明方法,这里仅作为例子加强大家对浮点数的理解。
题目描述: 怎么比较两个浮点数的大小?
任何抛弃精度谈浮点数的比较都是无意义的。但可以设置一定的精度来比较两个浮点数。
精度一般用希腊字母ε(epsilon)来表示。
程序代码如下:(源码文件:ch02/float_compare_epsilon.php)
<?php $epsilon = 1e-10;//精度为10的-10次方 $a = 0.3; $b = 0.1+0.2; //不使用精度 var_dump($a - $b == 0);//bool(false) //使用精度 var_dump(abs($a - $b) <= $epsilon);//bool(true) ?>