1. 浮点数的定义:
在数学中就是实数。
2. php定义举例:
$a = 1.234;
$b = 1.2e3;
$c = 7E-10;
3. php浮点型在计算机中采用IEEE754双精度格式表示:
十进制7 转化为二进制 0111 规格化科学计数法 1.11 ×2^2
在32位系统中:1位表示符号位(0) 8位表示阶码(00000010)23位表示尾数(1.11)
在64位系统中:1位表示符号位(0) 11位表示阶码(00000010)52位表示尾数(1.11)
注意:
1. 阶码在计算机中用移码表示 。
2.由于是规格化浮点数尾数的整数位始终是1,所以计算机中只表示尾数小数点后面的数字。
例子:十进制7 的阶码 10000010 尾数 1101
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
第一行为四个字节的地址,第二行为浮点数在计算机中的存储情况,当然计算机的实际情况远比这个复杂,这个只是逻辑上的存储情况。
尾数的计算过程中:十进制整数转化为2进制整数用除2取余法,十进制小数转化为二进制小数采用乘2取整法。(具体算法可以自行百度)
4. php中使用浮点数的注意事项:
(1) 浮点数是不能比较相等的。
var_dump(0.8=0.7+0.1); //bool(false) 原因:0.1、0.7、0.8在计算机中都不能精确表示
var_dump(1.0=0.5+0.5);//bool(true) 原因:0.5、1.0都可以精确表示
(2)要测试浮点数是否相等,要使用一个仅比该数值大一丁点的最小误差值。该值也被称为机器极小值(epsilon)或最小单元取整数,是计算中所能接受的最小的差别值。
$a = 1.23456789;
$b = 1.23456780;
$epsilon = 0.00001;
if(abs($a-$b) < $epsilon) {
echo "true";
}
(3) bcmath 任意精度数学
参考地址:BC Math
bccomp — 比较两个任意精度的数字:
int bccomp ( string $left_operand , string $right_operand [, int $scale = int ] )
如果两个数相等返回0, 左边的数left_operand
比较右边的数right_operand
大返回1, 否则返回-1.
echo bccomp('1', '2') . "\n"; // -1
echo bccomp('1.00001', '1', 3); // 0
echo bccomp('1.00001', '1', 5); // 1
(4) NAN
某些数学运算会产生一个由常量 NAN 所代表的结果。此结果代表着一个在浮点数运算中未定义或不可表述的值。任何拿此值与其它任何值(除了TRUE)进行的松散或严格比较的结果都是 FALSE。
由于 NAN 代表着任何不同值,不应拿 NAN 去和其它值进行比较,包括其自身,应该用 is_nan() 来检查。
var_dump(acos(2)); //float(NAN)