Простейший код: PHP: <?php echo '<table cellspacing=0 cellpadding=2 border=1> <tr> <td>Оригинал</td> <td>intval()</td> <td>round()</td> <td>floor()</td> <td>ceil()</td> </tr>'; $num=2.90; for($i=0;$i<5;++$i){ echo '<tr> <td>'.$num.'</td> <td>'.intval($num).'</td> <td>'.round($num).'</td> <td>'.floor($num).'</td> <td>'.ceil($num).'</td> </tr>'; $num+=0.05; } echo '</table>'; ?> выдает: Вопрос: почему в строке, где оригинал=3, intval=2 и floor=2? PHP Version 5.2.17 .
Полазил по форумам: Как понял это мудреная особенность языка. Выглядит как глюк и не лечится. Другими словами: это глюк, имеющий объяснение. Но нужно не объяснение, а работающая функция, по этому выход один: писать свою функцию. Если ошибаюсь, поправьте...
PHP: <?php echo '<table cellspacing=0 cellpadding=2 border=1> <tr> <td>Оригинал</td> <td>intval()</td> <td>round()</td> <td>floor()</td> <td>ceil()</td> <td>var_dump()</td> </tr>'; $num=2.90; for($i=0;$i<5;++$i){ echo '<tr> <td>'.$num.'</td> <td>'.intval($num).'</td> <td>'.round($num).'</td> <td>'.floor($num).'</td> <td>'.ceil($num).'</td><td>'; var_dump($num); echo '</td></tr>'; $num+=0.05; } echo '</table>'; ?> Код (Text): Оригинал intval() round() floor() ceil() var_dump() 3 2 3 2 3 float(3)
А то, что 2.95 + 0.05 = 2.9999~, т.е. float, но отображается с округлением. intval при конвертировании отсекает мантиссу и получается 2. И это не глюк языка. http://habrahabr.ru/blogs/cpp/112953/
Более краткая демонстрация, не глюка: $i=2.990; $i+=0.005; $i+=0.005; echo intval($i); == 3 $i=2.90; $i+=0.05; $i+=0.05; echo intval($i); == 2 $i=2.0;$i+=0.9999999999999999;echo intval($i); == 3 $i=2.0;$i+=0.999999999999999;echo intval($i); == 2 до кучи: $i=2.0; $i+=0.5; $i+=0.5; echo intval($i); == 3 $i=2.0; $i+=0.50; $i+=0.50; echo intval($i); == 3 $i=2.0; $i+=0.55; $i+=0.45; echo intval($i); == 3 $i=2.8; $i+=0.1; $i+=0.1; echo intval($i); == 3 $i=2.90; $i+=0.10; echo intval($i); == 3 $i=2.9; $i+=0.1; echo intval($i); == 3 $i=2.995; $i+=0.005; echo intval($i); == 3 $i=2.80; $i+=0.05; $i+=0.15; echo intval($i); == 2 $i=2.90;$i+=0.0500000000000000;$i+=0.0500000000000000;echo intval($i); == 2 $i=2.90;$i+=0.0500000000000001;$i+=0.0500000000000001;echo intval($i); == 3 $i=2.90;$i+=0.05000000000000001;$i+=0.05000000000000001;echo intval($i); == 2
да косяк это, ежу понятно. если вардамп выводит как тройку, а интвал как двойку - бяда. просто зная что работаешь с флоатами надо юзать не интвал