2017-01-19 5 views
7

documentationには、範囲の$endが含まれていると記載されています。これはほとんどの場合ですが、$end$stepの両方が浮動小数点の場合、最後の値はありません。何故ですか?floatの範囲と間隔で指定するとrange()が含まれないのはなぜですか?

print_r(range(1, 13, 1)); 
print_r(range(1, 13, 0.1)); 
print_r(range(0.1, 1.3, 0.1)); 

出力:

Array 
(
    [0] => 1 
    [1] => 2 
    // ... 
    [11] => 12 
    [12] => 13 
) 
Array 
(
    [0] => 0.1 
    [1] => 0.2 
    // ... 
    [119] => 12.9 
    [120] => 13 
) 
Array 
(
    [0] => 0.1 
    [1] => 0.2 
    // ... 
    [10] => 1.1 
    [11] => 1.2 
    // 12 => 1.3 is missing 
) 
+0

興味深いです。おそらくPHP 7のバグでしょうか? –

+2

浮動小数点は近似値です。あなたが '0.1'だけインクリメントすると、必ずしも終わりの部分に正確に当たってしまうわけではありません。 – Barmar

+1

はい、PHP7 https://3v4l.org/kp1Fvのようです – AbraCadaver

答えて

3

範囲は包括的です。ただし、加算する数値についての仮定は正しくありません。

0.1は正確な精度でバイナリ表現できません。 PHPの計算でそれを使用すると、実際には少し高いまたは低い数値が得られます。次codepadを見てみましょう:

http://codepad.org/MkoWgAA1

<?php 

$sum = 1.0 + 0.1 + 0.1; 

if ($sum > 1.2) { 
    print("1.2 > 1.2"); 
} else if ($sum < 1.2) { 
    print("1.2 < 1.2"); 
} else { 
    print("1.2 == 1.2"); 
} 

出力:

1.2 > 1.2 
+0

興味深いことに、これは、私の例とは異なり、バージョン5.6 - 7.0.2(HHVMと同様)で期待される結果を生成するのとは異なり、[3v4l](https://3v4l.org/QYgXR)でサポートされているすべてのバージョンで全く同じ結果が得られます。バージョン7.0.3 - 7.1.1での浮動小数点精度のオーバートリップ – nCrazed

関連する問題