2017-01-19 19 views
7

Pod numerem documentation jest dostępny zakres $end. I tak jest przez większość czasu, ale gdy zarówno $end jak i $end i $step są spławiane, brakuje ostatniej wartości. Dlaczego?Dlaczego zakres() nie jest uwzględniany, gdy jest podany w zakresie zmiennoprzecinkowym i interwałach?

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

wyjściowa:

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

Interesujące. Może błąd w PHP 7? –

+2

Wartość zmiennoprzecinkowa jest przybliżona. Kiedy inkrementujesz o "0.1", nie zawsze trafisz dokładnie na koniec. – Barmar

+1

Tak, wydaje się być PHP7 https://3v4l.org/kp1Fv – AbraCadaver

Odpowiedz

3

Zakres wynosi włącznie; jednak twoje założenia dotyczące sumowania liczb są nieprawidłowe.

0.1 nie może być reprezentowany w systemie binarnym z dokładnością. Gdy użyjesz go w obliczeniach w php, otrzymasz liczbę, która jest trochę wyższa lub niższa. Spójrz na poniższy 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"); 
} 

wyjściowa:

1.2 > 1.2 
+0

Co ciekawe, daje to dokładnie takie same wyniki we wszystkich wersjach obsługiwanych przez [3v4l] (https://3v4l.org/QYgXR) w przeciwieństwie do mojego przykładu, który daje oczekiwany wynik w wersji 5.6 - 7.0.2 (jak również HHVM), ale przejazdy nad dokładnością zmiennoprzecinkową w wersjach 7.0.3 - 7.1.1 – nCrazed