首頁 >後端開發 >php教程 >關於php 浮點數比較方法 的講解

關於php 浮點數比較方法 的講解

jacklove
jacklove原創
2018-06-09 10:32:341515瀏覽

浮點數運算精確度問題

首先來看一個範例:

<?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.00000000000000000000printf("%.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的二進制為

1000.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);                   // falsevar_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);          // falsevar_dump(bcsub($c, $b, 1)==$a); // true?>
###本文講解了關於php 浮點數比較方法,更多相關內容請關注php中文網。 ######相關推薦:#########透過mysql匯出查詢結果到csv方法的解說###############php array_push 與$arr[] =$value 之間的效能比較###############如何利用php設定一個嚴格控制過期時間的session#########

以上是關於php 浮點數比較方法 的講解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

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