2015-12-16 7 views
0

Почему мой цикл for с поплавковым шагом (0.1) не выполняет последнюю итерацию в PHP - любая версия?Почему для шага поплавка не выполняет последнюю итерацию?

Мой код теста:

$procents_list = []; 

for($i = 0.5; $i <= 1.5; $i += 0.1) 
{ 
    $procents_list[] = $i; 
} 

print_r($procents_list); 

Итерация от 5 до 15 с шагом 1 все ок. Почему это печать:

Array 
(
    [0] => 0.5 
    [1] => 0.6 
    [2] => 0.7 
    [3] => 0.8 
    [4] => 0.9 
    [5] => 1 
    [6] => 1.1 
    [7] => 1.2 
    [8] => 1.3 
    [9] => 1.4 
) 
+1

[читать, учиться и внутренне переваривать] (https: // эн. wikipedia.org/wiki/Floating_point#Accuracy_problems) –

+1

Также прочитайте [соответствующий раздел документов PHP] (http://www.php.net/manual/en/language.types.float.php), в котором объясняется, как сравнивать с плавающей точкой значения –

+0

0,5000008 0,6000008 0.7000008 0,8000008 0,9000008 1.0000008 1.1000008 1.2000008 1.3000008 1.4000008 – qRoC

ответ

2

Компьютеры используют Base-2 (0,1) вместо Base-10 (0,1,2, ... 9) для представления чисел. В Base-10 некоторые цифры не могут быть представлены точно (например, 1/3 = 0,33333). В Base-2 другой набор чисел не может быть представлен точно. Фактически, 1/10, который равен 0,1 в десятичном значении, не имеет точного представления в двоичном формате. Таким образом, математика с поплавками может делать странные вещи и никогда не должна восприниматься как точные значения.

Я не мог понять, как получить PHP, чтобы распечатать все цифры без округления, но писать тот же самый пример в Java выводит следующие значения:

0.5 
0.6 
0.70000005 
0.8000001 
0.9000001 
1.0000001 
1.1000001 
1.2000002 
1.3000002 
1.4000002 

Таким образом, значение, которое вы получали был немного больше 1,5, и петля таким образом закончилась.

В этом случае одна альтернатива просто использовать целые числа для цикла и разделить на 10, помещая их в массив:

$procents_list = []; 

for ($i = 5; $i <= 15; $i += 1) 
{ 
    $procents_list[] = $i/10; 
} 

print_r($procents_list); 
Смежные вопросы