Форум программистов, компьютерный форум, киберфорум
PHP для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.65/57: Рейтинг темы: голосов - 57, средняя оценка - 4.65
156 / 20 / 5
Регистрация: 21.02.2009
Сообщений: 2,787

Универсальное округление цен

07.12.2012, 12:09. Показов 11549. Ответов 14
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Предположим, что цена товара составляет 350 рублей. Если объявить на него скидку в 3 процента, то получается новая цена 339 рублей 50 копеек.

Такое значение во многих случаях не устраивает, поскольку некоторые кассиры отказываются от копеек, а иногда директора магазинов предпочитают иметь цены, кратные 5 или 10 рублям.

В этой связи возникает такая задача: как средствами РНР округлить цену с заранее заданной точностью?

То есть, если задан коэффициент $k_t = 1, $k_t = 2, $k_t = 5, $k_t = 10, $k_t = 20, $k_t = 50, $k_t = 100, то цена округляется по правилам округления соответственно до рублей, до двух рублей, до пяти рублей, до десяти рублей, до двадцати рублей, до пятидесяти и до ста рублей.
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
07.12.2012, 12:09
Ответы с готовыми решениями:

Google spreadsheet округление цен по определенной формуле
Форумчане, Нужна помощь, немогу решить как придумать. Ситуация след. есть гигантский список в google spreadsheet в котором идут...

Универсальное решение
Как в этом куске кода заменить эту часть ('продукт') на что-нибудь универсальное т.к там может быть Любое слово? ...

Универсальное ЗУ li-pol/ni-mh на МК.
Доброго времени суток. Есть радиоуправляемая машинка. В ней есть Ni-Mh аккум 7.2 В. 3000 мА. С его зарядкой проблем нет. А тут решил...

14
130 / 117 / 30
Регистрация: 14.11.2010
Сообщений: 707
07.12.2012, 12:20
читаем round()
PHP
1
2
3
4
5
6
7
8
9
10
<?php
echo round(3.4);         // 3
echo round(3.5);         // 4
echo round(3.6);         // 4
echo round(3.6, 0);      // 4
echo round(1.95583, 2);  // 1.96
echo round(1241757, -3); // 1242000
echo round(5.045, 2);    // 5.05
echo round(5.055, 2);    // 5.06
?>
0
156 / 20 / 5
Регистрация: 21.02.2009
Сообщений: 2,787
07.12.2012, 12:33  [ТС]
round эту задачу не решает (иначе его бы и взяли), поскольку он оперирует только десятичными знаками.
0
Почетный модератор
Эксперт HTML/CSSЭксперт PHP
 Аватар для KOPOJI
16844 / 6724 / 880
Регистрация: 12.06.2012
Сообщений: 19,967
07.12.2012, 13:32
number_format() / printf() ?
0
156 / 20 / 5
Регистрация: 21.02.2009
Сообщений: 2,787
07.12.2012, 13:46  [ТС]
Вроде бы, эти функции совсем другое делают?

Как мне кажется, для решения этой задачи без скрипта не обойтись. Что-нибудь на основе round придется сделать...
0
130 / 117 / 30
Регистрация: 14.11.2010
Сообщений: 707
07.12.2012, 14:05
Цитата Сообщение от vlad-55 Посмотреть сообщение
основе round
Понятное дело. Вы хотя бы наброски кода сделали, не будут же за Вас все писать...
0
156 / 20 / 5
Регистрация: 21.02.2009
Сообщений: 2,787
07.12.2012, 14:12  [ТС]
Проблема разрешилась.
0
130 / 117 / 30
Регистрация: 14.11.2010
Сообщений: 707
07.12.2012, 14:13
Цитата Сообщение от vlad-55 Посмотреть сообщение
Проблема разрешилась.
расскажите всем, как решили
0
156 / 20 / 5
Регистрация: 21.02.2009
Сообщений: 2,787
07.12.2012, 14:32  [ТС]
Так:

PHP
1
2
3
4
5
6
7
8
9
10
11
12
    $cena = 157.51;
    $pogp = 2;
 
function my_round($arg, $base){
    //arg - округляемое число, $base - "округлитель"
    $ost = $arg%$base; //вычисляем остаток от деления
    $chast = floor($arg/$base); //находим количество целых округлителей в аргументе
    if($ost >= $base/2)    $rez = ($chast+1) * $base; //выбираем направление округления
    else $rez = $chast * $base;
    return $rez;
}
echo "<br /><br />cena $cena pogp $pogp " . my_round($cena, $pogp); //160
0
5 / 4 / 4
Регистрация: 03.09.2012
Сообщений: 91
07.12.2012, 15:44
у меня выводит 158, как будто обычное округление
0
156 / 20 / 5
Регистрация: 21.02.2009
Сообщений: 2,787
07.12.2012, 16:26  [ТС]
Так и должно быть при дискретности 2.

Попробуйте $pogp = 20.
0
5 / 4 / 4
Регистрация: 03.09.2012
Сообщений: 91
07.12.2012, 16:38
я подумал $pogp означает сколько нулей должно быть в конце.
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$cena = 1576.42;
$pogp = 2;
function my_round($arg, $base){ 
 
    $arg = floor($arg); //удаляем дробную часть
    $last_nums = substr($arg, -$base); //отделяем последние цифры для сравнения
    $a = pow(10, $base);
    $okr = (5 * $a)/10;
    if($last_nums >= $okr)
    {
        $nedostatok = $a - $last_nums;
        $rez = $arg + $nedostatok;
    }
    else $rez = $arg - $last_nums;
    return $rez;
}
 
echo "<br />" . my_round($cena, $pogp); //1600
Добавлено через 3 минуты
$arg = floor($arg); можно заменить на round если это вам важно, но по математическим правилам думаю в таких случаях округлять надо вниз
0
156 / 20 / 5
Регистрация: 21.02.2009
Сообщений: 2,787
07.12.2012, 17:11  [ТС]
Мне как-то не удается уловить различие в результатах.

В той функции, что я привел выше, Вы обнаружили какой-то дефект?
0
5 / 4 / 4
Регистрация: 03.09.2012
Сообщений: 91
07.12.2012, 17:27
Цитата Сообщение от vlad-55 Посмотреть сообщение
В той функции, что я привел выше, Вы обнаружили какой-то дефект?
нет, у вас все прекрасно работает) просто я по другому понял суть переменной $pogp.

Цитата Сообщение от vlad-55 Посмотреть сообщение
Мне как-то не удается уловить различие в результатах.
в моем примере если $pogp равна 2, то цена округляется до двух нулей, то есть $cena = 1576.42 будет 1600
0
 Аватар для duzorg
52 / 48 / 2
Регистрация: 14.03.2012
Сообщений: 194
21.04.2018, 13:53

Не по теме:

Некропост, но всё же, так как поисковик кидает на эту тему, внесу небольшие поправки.


Функция выше не очень подходит для округления цен с копейками по правилам, положенным по закону (нельзя округлять в пользу продавца).
А так как на носу у нас ФЗ-54 и необходимо было переписывать дисконтную систему, сам столкнулся с такой проблемой и пришлось потратить время для того, чтобы создать универсальный способ, который работает корректно, независимо от того, какой способ округления чисел с плавающей запятой установлен в php.ini (параметр precision).
Документация PHP
precision integer
Количество значащих цифр, отображаемых для чисел с плавающей точкой. -1 означает, что будет использован усовершенствованный алгоритм для округления таких чисел.
Соль в том, что используя стандартные методы округления в зависимости от того, что установлено в данном параметре, мы могли получать разные результаты, например: 16,65 при округлении до 5 копеек могла округлиться до 16,65, а могла до 16,60...

В общем вот код, который корректно, согласно букве закона, округляет переданную ему цену до указанной точности. Может быть кому-то будет полезно.
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# Функция округления цены до нужной точности
function rounding_price($price, $precision){
    # $price - принимает цену, которую необходимо округлить
    # $precision - указывает точность до которой необходимо выполнить округление
    #     0.01 - округление цены до копеек (минимально-возможная цена)
    #     0.05 - округление цены до 5 копеек
    #     0.10 - округление цены до 10 копеек
    #     0.50 - округление цены до 50 копеек
    #     1.00 - округление цены до 1 рубля (копейки будут откинуты)
    $price = intval(round($price * 100, 3));
        // В переменной $price, в round второй аргумент указывает сколько знаков
        // (не считая копеек) стоит игнорировать математическое округление
        // То есть в строке $price = intval(round($price * 100, 3)) имеет значение 3
        // значит 5 знаков (3 указанных, и 2 знака копеек) после запятой
        // не будут использоваться для математического округления
        // 16,49 999  - будет преобразовано в 16,49 (при 0,01) или 16,45 (при 0,05) или 16,40 (при 0,10)
        // 16,49 9994 - будет преобразовано в 16,49 (при 0,01) или 16,45 (при 0,05) или 16,40 (при 0,10)
        // 16,49 9995 - будет преобразовано в 16,50
        // 16,49 9999 - будет преобразовано в 16,50
    $precision = round($precision, 2);
    return round(floor(floor($price / $precision / 100)) * $precision, 2);
}
 
$price = 16.499999;
$precision = 0.05;
echo rounding_price($price, $precision);
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
21.04.2018, 13:53
Помогаю со студенческими работами здесь

Универсальное перетаскивание
В общем есть такое перетаскивание.как можно его сделать универсальным? ну т.е. чтобы работала для любого обьекта в котором вызвана эта...

Универсальное АЛУ
Не могу понять как реализовано !Fвх в таблице и Pвх. Книга Марченко Основы электроники.

Универсальное хэширование
Помогите разобраться с алгоритмом хэширования. Задание построить таблицу идентификаторов Вариант 14. Реализовал, но потом понял что...

универсальное множество
Помогите пожалуста! Заданная универсальное множество X = {1, 2, 3, ..., 40}. Необходимо задать множества А, В, С Х, т.е. множества,...

Универсальное название папки
Нужно откопировать файлы в директорию C:\Users\user\Favorites\Links,но так как у каждого пользователя имя уникальное,пытался поставить...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru