За последние 24 часа нас посетили 16056 программистов и 1420 роботов. Сейчас ищут 814 программистов ...

Почему INTVAL(3)=2 ?!

Тема в разделе "PHP для новичков", создана пользователем Настикс, 17 апр 2011.

  1. Настикс

    Настикс Активный пользователь

    С нами с:
    3 апр 2010
    Сообщения:
    17
    Симпатии:
    0
    Простейший код:
    PHP:
    1. <?php
    2. echo '<table cellspacing=0 cellpadding=2 border=1>
    3. <tr>
    4. <td>Оригинал</td>
    5. <td>intval()</td>
    6. <td>round()</td>
    7. <td>floor()</td>
    8. <td>ceil()</td>
    9. </tr>';
    10. $num=2.90;
    11.     for($i=0;$i<5;++$i){
    12.     echo '<tr>
    13.     <td>'.$num.'</td>
    14.     <td>'.intval($num).'</td>
    15.     <td>'.round($num).'</td>
    16.     <td>'.floor($num).'</td>
    17.     <td>'.ceil($num).'</td>
    18.     </tr>';
    19.     $num+=0.05;
    20.     }
    21. echo '</table>';
    22. ?>
    выдает:[​IMG]

    Вопрос: почему в строке, где оригинал=3, intval=2 и floor=2?
    PHP Version 5.2.17


    .
     
  2. Настикс

    Настикс Активный пользователь

    С нами с:
    3 апр 2010
    Сообщения:
    17
    Симпатии:
    0
    Полазил по форумам:
    Как понял это мудреная особенность языка. Выглядит как глюк и не лечится.
    Другими словами: это глюк, имеющий объяснение. Но нужно не объяснение, а работающая функция, по этому выход один: писать свою функцию.
    Если ошибаюсь, поправьте...
     
  3. Kreker

    Kreker Старожил

    С нами с:
    8 апр 2007
    Сообщения:
    5.433
    Симпатии:
    0
    <td> '.var_dump($num).' '.intval($num).'</td>
     
  4. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    PHP:
    1. <?php
    2.  echo '<table cellspacing=0 cellpadding=2 border=1>
    3. <tr>
    4. <td>Оригинал</td>
    5. <td>intval()</td>
    6. <td>round()</td>
    7. <td>floor()</td>
    8. <td>ceil()</td>
    9. <td>var_dump()</td>
    10. </tr>';
    11.  $num=2.90;
    12.      for($i=0;$i<5;++$i){
    13.      echo '<tr>
    14.     <td>'.$num.'</td>
    15.     <td>'.intval($num).'</td>
    16.     <td>'.round($num).'</td>
    17.     <td>'.floor($num).'</td>
    18.     <td>'.ceil($num).'</td><td>';
    19.      var_dump($num);
    20.      echo '</td></tr>';
    21.      $num+=0.05;
    22.      }
    23.  echo '</table>';
    24.  ?>
    Код (Text):
    1. Оригинал intval() round() floor() ceil() var_dump()
    2.  3         2       3        2      3      float(3)
     
  5. Настикс

    Настикс Активный пользователь

    С нами с:
    3 апр 2010
    Сообщения:
    17
    Симпатии:
    0
  6. Shumomer

    Shumomer Активный пользователь

    С нами с:
    12 мар 2011
    Сообщения:
    194
    Симпатии:
    1
    Адрес:
    из вашего вображения
    Есть такое дело. Поэтому всегда пишу так:

    echo intval(''.$num);

    Маразм и костыль, но что делать.
     
  7. Kreker

    Kreker Старожил

    С нами с:
    8 апр 2007
    Сообщения:
    5.433
    Симпатии:
    0
    А то, что 2.95 + 0.05 = 2.9999~, т.е. float, но отображается с округлением. intval при конвертировании отсекает мантиссу и получается 2.
    И это не глюк языка. http://habrahabr.ru/blogs/cpp/112953/
     
  8. Kreker

    Kreker Старожил

    С нами с:
    8 апр 2007
    Сообщения:
    5.433
    Симпатии:
    0
    Не конвертировать float в int.
     
  9. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.559
    Симпатии:
    632
    int, float, double... Работайте со строками и будет вам счастье!
     
  10. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.559
    Симпатии:
    632
    PHP:
    1. echo intval("$num");
     
  11. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    а давно у нас математику обновили так что стало 2.95 + 0.05 = 2.9999?? :D
     
  12. Настикс

    Настикс Активный пользователь

    С нами с:
    3 апр 2010
    Сообщения:
    17
    Симпатии:
    0
    Более краткая демонстрация, не глюка:

    $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
     
  13. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    да косяк это, ежу понятно. если вардамп выводит как тройку, а интвал как двойку - бяда.

    просто зная что работаешь с флоатами надо юзать не интвал
     
  14. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.559
    Симпатии:
    632
    а round(), что логично