php中浮點數(shù)的精度值是用來控制輸出該浮點數(shù)時使用的,可以理解為控制輸出的位數(shù),精度值不同,看到輸出結果也可能不一樣,注意:其內部還是按照實際值存儲的,當兩個浮點數(shù)進行四則運算時,用的還是其本來的值。
php的配置文件中使用precision來設定全局指定浮點數(shù)的精度值,似乎每個發(fā)行版,它的默認設置都不太一樣,我在window下看到是12,在linux下看到此值是14,當然也可以通過程序中使用ini_set來改變全局設置,例如:
ini_set("precision", "15");
對于精度我一直理解為小數(shù)點后保留多少,那么在php的浮點數(shù)中是這樣的么?答案是否定的。
浮點數(shù)其實是整數(shù)部分和小數(shù)部分組成,這里的精度是指整數(shù)部分的位數(shù)加小數(shù)部分的位數(shù)不能超過其精度最大值,如果超過,則按照四舍五入的方法截斷到最大的精度值。整數(shù)部分如果是0,則不計位數(shù),小數(shù)部分末尾0也不計入位數(shù)。另外對于同一個數(shù),precision的不同,可能顯示的出來表現(xiàn)形式也不一樣。下面通過例子的方式來說明。
整數(shù)部分為 0 情況,代碼如下:
- $num = 0.12345600000000000;
- //整數(shù)部分為0 ,位數(shù)為 0 ,小數(shù)部分末尾的 0 不計入位數(shù),所以總位數(shù)為 6
- ini_set("precision", "12");
- echo $num; // 0.123456
- //未超過精度值,顯示的結果為 0.123456
- ini_set("precision", "3");
- echo $num; // 0.123
- //超過精度值,保留3位
- ini_set("precision", "5");
- echo $num; // 0.12346
- //超過精度值,保留5位這種情況下,精度值等價于小數(shù)點后保留幾位。
整數(shù)部分大于 0 情況,代碼如下:
- $num = 12.12345600000000000;
- //整數(shù)部分為12 ,位數(shù)為 2 ,小數(shù)部分末尾的 0 不計入位數(shù),位數(shù)為6,所以總位數(shù)為 2 + 6
- ini_set("precision", "12");
- echo $num; // 12.123456
- //未超過精度值,顯示的結果為 12.123456
- ini_set("precision", "3");
- echo $num; // 12.1
- //超過精度值,整數(shù)部分位數(shù)為 2 ,所以只保留一位小數(shù)
- ini_set("precision", "5");
- echo $num; // 12.123
- //超過精度值,整數(shù)部分位數(shù)為 2 ,所以只保留3位小數(shù)可以看到小數(shù)點后保留的位數(shù)跟精度已經整數(shù)部分的位數(shù)有關。
整數(shù)部分大于 0 情況 之二,代碼如下:
- $num = 12345678.12345600000000000;
- //整數(shù)部分為12345678 ,位數(shù)為 8 ,小數(shù)部分末尾的 0 不計入位數(shù),位數(shù)為6,所以總位數(shù)為 8 + 6
- ini_set("precision", "12");
- echo $num; // 12345678.1235
- //超過精度值,顯示的結果為 12345678.1235
- ini_set("precision", "3");
- echo $num; // 1.23E+7
- //超過精度值,且整數(shù)部分位數(shù)超過精度,小數(shù)部分舍棄,且整數(shù)部分只取3位
- ini_set("precision", "5");
- echo $num; // 12346000
- //超過精度值,且整數(shù)部分位數(shù)超過精度,小數(shù)部分舍棄,且整數(shù)部分只取5位
上述例子中可以看到,精度值也關系到整數(shù)部分的截取,注意到最后兩個例子中顯示的方式不一樣,一個是使用科學計數(shù)法,一個是后面用 0 補,通過實驗得出的結論是當整數(shù)部分的位數(shù)減去 精度值 大于 4 的時候,使用科學計數(shù)法的方式,否則后面用 0 補,換句話說,就是整數(shù)部分位數(shù)超過精度值后,截斷后,補 0 的個數(shù)不會超過 4.
浮點數(shù)運算,代碼如下:
- $num1 = 1331625729.687;
- $num2 = 1331625730.934;
- ini_set("precision", "8");
- echo $num1 . '
- ';
- echo $num2 . '
- ';
- $sub = $num1 - $num2;
- echo $sub . '
- ';
- //輸出的結果為:
- /*
- 1331625700
- 1331625700
- -1.247
- */
上述例子就說明了精度值只是控制顯示結果,內部存儲還是原始值,所以 $sub 的值為1331625729.687減1331625730.934。
PHP內置的echo, var_dump,json_encode,字符串拼接等函數(shù)(指令)在顯示浮點數(shù)時都有問題,導致精度丟失.實例代碼如下:
- <?php
- $a = 1315537636.338467;
- printf("%f", $a); echo "n";
- echo $a . "n";
- echo $a; echo "n";
- ?>
- /*結果
- 1315537636.338467
- 1315537636.3385
- 1315537636.3385
- */
也就是說,用PHP最順手的方法將浮點數(shù)轉成字符串或者顯示是不行的,必須使用printf/sprintf將浮點數(shù)轉成字符串.
新聞熱點
疑難解答