浮点数
运算的精度问题
首先,看一个例子:
< PHP
$ = 0.1;
$ = 0.9;
$=1;
var_dump((($ + $ B)= = $ C);
var_dump((($ C $ B)= =美元);
>
$ $ = $ = C返回true,
正确 $ = $ a = a返回false,
错误 为什么会这样
操作之后,当精度为20位时,实际返回的内容如下所示:
< PHP
$ = 0.1;
B = 0.9美元;
$=1;
printf(%。20层$ + $ B); / / 1.00000000000000000000
printf(%。20楼C B美元美元); / / 0.09999999999999997780
>
C B 0.09999999999999997780美元美元,所以返回假比0.1
这个问题是由于浮点数计算的准确性和浮点数
转换为二进制数时精度下降的可能性。
浮点数转换二进制
方法 积分部分用2余项方法进行划分。
乘2种方法的小数部分
例如,将数字8.5转换为二进制。
整数部分为8。
8 2 = 4 8% 2 = 0
4 2 = 2 4% 2 = 0
2 2 = 1 2% 2 = 0
1是小于2,所以不需要计算。整数8的二进制数是1000。
小数部分是0.5。
0.5x2 = 1
因为舍入小数部分为0,因此不需要计算。
十进制0.5的二进制数是0.1。
8.5的二进制数是1000.1。
计算数字0.9的二进制数
0.9x2 = 1.8
0.8x2 = 1.6
0.6x2 = 1.2
0.2x2 = 0.4
0.4x2 = 0.8
0.8x2 = 1.6
……
连续循环后,当拦截精度N,N后数将被消除,造成精度损失。
在本例中,0.9依次丢失精度二进制,比较时产生错误。
所以千万不要相信浮点数是精确到最后的,永远不要比较两个浮点数是否相等。
正确比较浮点数的一种方法
1。用圆法进行比较和比较
实例uff1a
< PHP
$ = 0.1;
B = 0.9美元;
$=1;
var_dump(($ C $ B)= = $ / /假);
var_dump(圆(($ C $ B),1)= =圆($,1); / /真实)
>
2。采用高精度的
操作方法 在第一次操作中,使用高精度的操作方法,以确保精度不会丢失。
高精度操作方法如下:
高精度的数字增加了两bcadd
bccomp比较两个高精度的数字,返回-1,0,1
bcdiv两高精度数字鸿沟
高精度数字余数bcmod
bcmul将两个高精度数
高精度数字电力bcpow
高精度数字电源模块bcpowmod
的bcscale
配置默认的小数位数相当于规模=公元前Linux
对于高精度的平方根bcsqrt
bcsub减去两个高精度数字
实例uff1a
< PHP
$ = 0.1;
B = 0.9美元;
$=1;
var_dump(($ C $ B)= = $ / /假);
var_dump(bcsub($,$,1); / /真实= =美元)
>
以上是本文的全部内容,希望本文的内容能给大家的
学习或
工作带来一定的帮助,同时也希望能给予更多的
支持!