首頁  >  文章  >  後端開發  >  php 浮點數怎麼進行比較?

php 浮點數怎麼進行比較?

怪我咯
怪我咯原創
2017-07-11 13:58:494050瀏覽

浮點數在轉換過程中都會有誤差的,所以浮點數不能直接比較其大小,一般在比較兩個浮點數的時候是比較他們之間的差值,如果兩個數之間的差值在一個能接受的範圍之內的話,那麼,我們就認為這兩個浮點數是相等的。本篇文章主要介紹了php浮點數比較方法,具有很好的參考價值。下面跟著小編一起來看下吧

浮點數運算精確度問題

先看一個例子:

<?php
$a = 0.1;
$b = 0.9;
$c = 1;
var_dump(($a+$b)==$c);
var_dump(($c-$b)==$a);
?>

$a+$b== $c 回傳true,正確
$c-$b==$a 回傳false,錯誤

為什麼會這樣呢?

運算後,精度為20位元時實際回傳的內容如下:

<?php
$a = 0.1;
$b = 0.9;
$c = 1;
printf("%.20f", $a+$b); // 1.00000000000000000000
printf("%.20f", $c-$b); // 0.09999999999999997780
?>

$c-$b 為0.09999999999999997780,因此與0.1#比較回傳false

出現這個問題是因為浮點數計算涉及精確度,當浮點數轉為二進位時有可能會造成精度遺失。

浮點數轉二進位方法

整數部分採用除以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,因此不需要再計算下去

小數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.使用round方法處理後再比較

範例:

<?php
$a = 0.1;
$b = 0.9;
$c = 1;
var_dump(($c-$b)==$a);          // false
var_dump(round(($c-$b),1)==round($a,1)); // true
?>

2.使用高精度運算方法

先運算時,使用高精度的運算方法,這樣可以保證精度不會遺失。

高精度運算的方法如下:

#bcadd 將兩個高精度數字相加

bccomp 比較兩個高精度數字,回傳-1,0,1

bcp 將兩個高精度數字相除

bcmod# 求高精度數字餘數

bcmul 將兩個高精度數字相乘

bcpow 求高精度數字乘方

bcpowmod 求高精度數字乘方求模

bcscale 配置預設小數點位數,相當於Linux bc中的”scale=”

bcsqrt 求高精度數字平方根

bcsub 將兩個高精度數字相減

範例:

<?php
$a = 0.1;
$b = 0.9;
$c = 1;
var_dump(($c-$b)==$a);     // false
var_dump(bcsub($c, $b, 1)==$a); // true
?>

以上是php 浮點數怎麼進行比較?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn