Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > Perl: разработка для Web > Округляшка дает сбой |
Автор: MaxPayne 24.11.2014, 00:36 |
Столкнулся с удивительной штукой в интернет магазине, который я делал на PERL. Идет обсчет цены с учетом скидки - все ок. Но сегодня прошла цена 1890 и случилось нечто. PERL обсчитал 0% скидку и выдал цену 1880 (т.е. скидка в 10 рублей). Это мелочи, но хочется узнать в чем проблема. Тестировал с другими ценами - все ок. Подскажите... Формула такая: $summafullskidka = (int((($summa/100)*(100-$skidka))/10))*10; Соответственно SUMMA = 1890, SKIDKA =0. НА ВЫХОДЕ $summafullskidka = 1880 ИСКАЛ НА КАКОМ ЭТАПЕ И РАЗБИЛ НА ЧАСТИ: В КОНЦЕ КАЖДОЙ СТРОКИ РЕЗУЛЬТАТЫ ### $summa11 = $summa/100; 18.9 $summa22 = 100-$skidka; 100 $summa33 = $summa11*$summa22; 1890 $summa44 = $summa33/10; 189 $summa55 = (int($summa44)); 188 $summa66 = $summa55*10; 1880 ### Подключены только два модуля use CGI qw(:all); use DBI; |
Автор: igorold 24.11.2014, 07:23 | ||
Посмотри результат:
ну сделай проверку на условие $skidka = 0 или нет. Этот ответ добавлен с нового Винграда - http://ru.vingrad.com/Okruglyashka-dayet-sboy-id547253f7ae2015e8388b4567#findElement_E7045_5472b2bfae20150a77ddd067_0 |
Автор: Bulat 24.11.2014, 08:33 | ||||
Я так понимаю, что в это строке ты пытаешься округлить до целого числа. Только int
из перлдока You should not use this function for rounding. ну и далее все описано подробно. Если нужно именно округление - как вариант
|
Автор: MaxPayne 24.11.2014, 10:41 | ||||
Скидка ИМЕННО 0. |
Автор: tzirechnoy 24.11.2014, 14:27 |
Учитывая натуру перла (динамическая типизацыя, автоматические преобразования, машынные типы) -- я бы посоветовал для рассчёта денег взять Math::BigInt. Очень удобно -- значение всегда int, безо всяких альтэрнатив. То есть этот случай -- банален, конечно (если нет -- то тем более возьмите Math::BigInt), но он наглядно показывает -- что бывает если floating point использовать с деньгами. Ничего хорошэго. Дажэ если для промежуточных результатов рассчётов. |
Автор: MaxPayne 24.11.2014, 17:04 |
Поставил POSIX::ceil. Странно, я бы понял такое округление когда число было бы десятичным - типа 189.433234. А тут то целое число от 189 = 188. Не ожидал я такого от INT. |
Автор: tzirechnoy 24.11.2014, 17:22 |
1890/10 -- не будет цэлым числом. Поскольку цэлочисленного деления в perl вообще не предусмотрено. Добавлено через 5 минут и 28 секунд Да, про POSIX::ceil -- это, честно говоря, редкостный FAIL. Вы вообще не поняли, что произошло и что Вы сделали. Совсем. Я мог бы подсказать код, который делает правильно в данном конкретном случае -- но, истинно говорю вам, возьмите Math::BigInt и не используйте floating point для денег. Вы вряд ли скоро поймёте, что такое floating point, что у него за проблемы округления, почему int() в perl сделали именно так, какое округление -- правильное, и, наконец, почему floating point не стоит использовать для денег. Просто поверьте на слово, и возьмите BigInt. |
Автор: Bulat 24.11.2014, 18:18 |
Скорее поленился прочитать документацию. А чтива там на две минуты и ответ на все вопросы! ![]() Добавлено через 3 минуты и 24 секунды P.S. В Perl нет целых чисел(нет определения типов подобно С). ![]() ![]() |
Автор: tzirechnoy 24.11.2014, 19:31 | ||||
Есть. Например, сравни:
Несмотря на то, что число 4611686018427387904 вроде бы одно и тожэ -- оно вполне представимо и в цэлочисленном и в виде IEEE754 double, мы видим разницу между цэлым 4611686018427387904 и 4611686018427387904 с плавающей точкой. Но да, Ларри сделал многое, чтобы этих цэлых чисел было не видно и не слышно. По сути, действительно, можно сказать что цэлых чисел в перле нет -- есть только числа с плавающей точкой, всё остальное -- практически от них неотличимо. Соответственно, использовать перловые числа для хранения денег -- нельзя. Используйте строки, BigInt или выкручивайтесь ещё как-то. |
Автор: Bulat 24.11.2014, 20:58 |
Это пустой холивар... который никому не нужен... Глупость какая... Все зависит от мастерства, таланта и квалификации программиста, а не от того какой язык или технология используется... |
Автор: tzirechnoy 25.11.2014, 00:28 | ||
Я таких умных, которые считают, что всё зависит от их мастерства, таланта и квалификацыи -- периодически на Новорижском вижу. Вокруг них ещё менты и мужыки с болгарками часто ошываются. И труповозка чуть поодаль. Есть, знаете ли, некоторые простые и достаточно общепринятые правила. Ну там, не более 160 на нашых сраных дорогах (на лучшых из них), полторы секунды резерва, делать бэкапы, тренироваться восстанавливать бэкапы, не хранить деньги в флоатах. Их можно несоблюдать. Штраф жызнь сама выпишэт. |