За последние 24 часа нас посетили 24629 программистов и 1695 роботов. Сейчас ищут 836 программистов ...

глюки с дисятичными значениями

Тема в разделе "MySQL", создана пользователем BaranPHP, 4 май 2014.

  1. BaranPHP

    BaranPHP Новичок

    С нами с:
    24 янв 2014
    Сообщения:
    356
    Симпатии:
    0
    Имеется таблица `fakt` c полями:
    `tovk1` (Сравнение -float, Null-Нет, По умолчанию-0)
    `tovc1` (Сравнение -float, Null-Нет, По умолчанию-0)
    `tovk2` (параметры одинаковые)
    `tovс2`
    .............по порядку до:
    `tovk10`
    `tovс10`
    Имеется функция:
    Код (PHP):
    1. function allfaktsum(){
    2.     $query = "SELECT SUM( `tovc1`*`tovk1`+`tovc2`*`tovk2`+`tovc3`*`tovk3`+`tovc4`*`tovk4`+`tovc5`*`tovk5`+`tovc6`*`tovk6`+`tovc7`*`tovk7`+`tovc8`*`tovk8`+`tovc9`*`tovk9`+`tovc10`*`tovk10` ) FROM `fakt`";
    3.     $res = mysql_query($query) or die(mysql_query());
    4.     
    5.     $allfaktsum = mysql_result($res, 0);
    6.     return $allfaktsum;
    7. }
    Вывод на страницу:
    Код (PHP):
    1. $allfaktsum = allfaktsum(); echo $allfaktsum;
    Вывод на страницу происходит с глюком.
    Если все числа в столбцах целые то всё ок. Но если поставить десятичное или сотое значение то выводится:
    0.01 = 0.009999999776482582
    0.02 = 0.019999999552965164
    2.22 = 2.2200000286102295
    7659.39 = 7659.39013671875
    567891.04 = 567891.0625

    SQL Запрос в PHP_MyAdmin показывает аналогичную ошибку. У меня не правильный запрос или значение параметров для полей таблицы?
     
  2. Ke1eth

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

    С нами с:
    16 мар 2012
    Сообщения:
    1.073
    Симпатии:
    11
    Адрес:
    заблудилса
  3. igordata

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

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    Типо как это не победить. Только округлять. Но есть вроде тип decimail.
     
  4. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.156
    Симпатии:
    1.771
    Адрес:
    :сердА
    Это не глюк и не ошибка. Это надо читать матчасть про способы представления различных типов данных внутри машины. Это особенность хранения флоатов. По этой причине ни в одной системе(которую делали не криворукие балбесы, так что за 1С:Бухгалтерия я не ручаюсь), связанной с деньгами, к примеру, не используют числа с плавающей точкой. Целая часть отдельно, дробная отдельно. И то и то в виде integer.

    Добавлено спустя 19 минут 18 секунд:
    ВО, в тему -
    [​IMG]
     
  5. BaranPHP

    BaranPHP Новичок

    С нами с:
    24 янв 2014
    Сообщения:
    356
    Симпатии:
    0
    То есть в самом MySQL нет инструментов для корректного хранения сотых величин? Или просто не стоит доверять арифметические действия запросу?
     
  6. igordata

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

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    их в принципе нет.
    Но есть decimal =)
     
  7. BaranPHP

    BaranPHP Новичок

    С нами с:
    24 янв 2014
    Сообщения:
    356
    Симпатии:
    0
    Увидил и сразу в гугл. Прочитал мануал, попробовал никуя не пашет. Там же описание про money и smallmoney. Вот думаю то что надо. PHP_MyAdmin кажет фигу, нет у него таких закладок. Ну думаю не мой вариант видимо что decimail, что money и smallmoney.
    Ну думаю погуглю есчё. "Вон оно чё михалыч" оказывается надо подставлять без скобок. В мануале то decimal(а,в) где а=кол-во знаков, в=кол-во знаков после запятой а в PHP_MyAdmin просто а,в.

    Так может и money и smallmoney как то можно использовать? Я просто не умею. Ну а гугл на этот счёт ничего внятного не выдаёт по крайней мере на первом десятке ссылок. Или достаточно и decimal? Просто до сегодня я и с float глюков не видел. У меня даже запрос на сайте нормально работал потому как там все значения либо целые либо половинчатые (0.5). И вот сегодня я впервые добавил 0.99 и началось....
     
  8. igordata

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

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    хз
    я не вижу смысла хранить деньги в числах с плавающей запятой
     
  9. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.156
    Симпатии:
    1.771
    Адрес:
    :сердА
    дело не в MySQL, а в том, как данные представляются на низком уровне. Почитайте про способы хранения и обработки разных типов данных.
     
  10. BaranPHP

    BaranPHP Новичок

    С нами с:
    24 янв 2014
    Сообщения:
    356
    Симпатии:
    0
    А в чём их принято хранить? Приводить в целочисленные величины? К примеру в копейки. А при выводе конвертить в рубли. По тому же принципу как дата хранится в секундах?
     
  11. igordata

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

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
  12. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.156
    Симпатии:
    1.771
    Адрес:
    :сердА
    Либо использовать комбинированный метод хранения, где копейки и рубли у каждой величины хранятся в виде целочисленных значений. А представлять это в виде единого десятичного значения.