天天看點

PHP浮點數精度和比較

平時對于浮點數運用并不是很多,偶然的一次對浮點數進行了比較,卻出現了意外的結果,是以便翻查各種資料尋求原因,大緻弄明白了這個問題,我們先來看一個比較

$a = 1 - 9/10;
$b = 0.1;
if($a == $b){
    echo “相等”;
}else{
    echo "不相等";
}
           

打眼一看,這$a是0.1,$b也是0.1,那不就是相等嗎,但是如果你把代碼運作一遍你會發現,輸出的是不相等,很多疑問便跑出來了,為什麼?

如果你熟讀手冊的話,你會發現,浮點數章節中有大大的一個Warning,讨論的就是浮點數精度的問題,如果還想要了解更多,也可以看看浮點數指南。下方還列舉出來了如何比較兩個浮點數,當然除了手冊中提供的比較方法外,我們還可以借助BCMath,這是PHP提供的專門進行任意精度計算的函數。

當然這種情況并非PHP獨有,其他語言也存在,例如Java,這種所謂的bug是跨語言的。如果你使用Java,你會發現,變量a輸出的是0.09999999999999998,這樣一來,很直覺的就知道了,變量a和變量b并不相等,但是在PHP中,不管你用echo還是var_dump(),輸出的都是0.1,明明都是0.1,為什麼還不相等,這便會令人更加的迷惑和不解。PHP難道沒有函數可以輸出類似Java的結果嗎?其實是有的,隻是這個函數并不是經常用到,它就是var_export。

var_export($a);
           

當然想要輸出上述效果,PHP版本必須在5.4.22之後,在這個版本之前,仍然會輸出0.1。在php.ini中有參數serialize_precision用來設定輸出的精度,預設為17。如果PHP版本滿足要求的話,我們再來調用這個函數,便會得到0.099999999999999978這樣的結果。