Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft Access Новый топик    Ответить
 Особенности применения функции ROUND  [new]
Joss
Member

Откуда: г. Минск
Сообщений: 4908
Что нам говорит о ней справка? Вот что пишут здесь

Функция Round

Возвращает число, округленное до указанного количества десятичных разрядов.

Round(выражение[, количество_деятичных _знаков])

Синтаксис функции Round имеет следующие аргументы:

выражение - Обязательное. Числовое выражение, которое требуется округлить.

количество_деятичных _знаков - Необязательное. Число, указывающее количество цифр справа от десятичного разделителя включены округления. Если не указано, функция округляет число до ближайшего целого числа.

И больше ничего там не написано. Но поиск в интернете даёт следующее

Функция Microsoft Access Round возвращает число, округленное до указанного количества десятичных знаков. Однако функция Round ведет себя немного странно, поэтому, прежде чем использовать эту функцию, пожалуйста, прочитайте следующее:

Функция Round использует логику округления к четному. Если округляемое выражение заканчивается на 5, функция округления округляет выражение так, чтобы последняя цифра была четным числом.


Пример:

Round(12.55, 1)
Result: 12.6 (округление вверх)

Round(12.65, 1)
Result: 12.6 (округление вниз)

Round(12.75, 1)
Result: 12.8 (округление вверх)

Round(12.85, 1)
Result: 12.8 (округление вниз)

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

Round(12.55 + 0.005, 1)
Result: 12.6 (округление вверх)

Round(12.65 + 0.005, 1)
Result: 12.7 (округление вверх)

Round(12.75 + 0.005, 1)
Result: 12.8 (округление вверх)

Round(12.85 + 0.005, 1)
Result: 12.9 (округление вверх)

Другие предлагают прибавлять половинку предпоследнего знака при округлении

Round(12.55 + 0.05, 1)
Result: 12.6 (округление вверх)

Round(12.65 + 0.05, 1)
Result: 12.7 (округление вверх)

Round(12.75 + 0.05, 1)
Result: 12.8 (округление вверх)

Round(12.85 + 0.05, 1)
Result: 12.9 (округление вверх)

Третьи предлагают просто добавить к числу 0,0001

Round(12.55 + 0.0001, 1)
Result: 12.6 (округление вверх)

Round(12.65 + 0.0001, 1)
Result: 12.7 (округление вверх)

Round(12.75 + 0.0001, 1)
Result: 12.8 (округление вверх)

Round(12.85 + 0.0001, 1)
Result: 12.9 (округление вверх)

Во все случаях округление даёт верный результат.


-------------------------------------------------------------
А ты вложил уже свой кровный рубль в 50-ти миллиардное состояние Билла Гейтса?
1 фев 19, 11:27    [21799443]     Ответить | Цитировать Сообщить модератору
 Re: Особенности применения функции ROUND  [new]
Akina
Member

Откуда: Зеленоград, Москва, Россия
Сообщений: 19440
Ну да... а поисследовать всё то же, но для отрицательных? Картинка с другого сайта.

Я уж не говорю о том, что сколько не добавляй, всегда найдётся значение, которое даст неверный результат. Скажем, для наименьшего из предложенных выше 0,0001 такой казус будет, к примеру, со значением 12.644445.

Каждый тип округления требует своей собственной функции. К тому же учитывающей, что 0,5 в Single/Double может запросто оказаться как 0,499999..9999, так и 0,500000...0001.
1 фев 19, 12:24    [21799526]     Ответить | Цитировать Сообщить модератору
 Re: Особенности применения функции ROUND  [new]
ПЕНСИОНЕРКА
Member

Откуда: Владимирская обл
Сообщений: 4597
Joss
Функция Microsoft Access Round возвращает число, округленное до указанного количества десятичных знаков. Однако функция Round ведет себя немного странно, поэтому, прежде чем использовать эту функцию, пожалуйста, прочитайте следующее:


эта функция врала всегда, даже в древнем dBASE и foxPRO

столкнулись в расчете зарплаты, когда в расчете округлила некорректно ОТДЕЛЬНЫЕ значения сумм
причем не предсказуемо, например 100.1 округляло до 101рубля

написали программку, выловили еще несколько позиций --логики не поняли
---
перешли на округление str(сумма+0.005,2)
затем на str(сумма+0.0045,2)
1 фев 19, 12:39    [21799549]     Ответить | Цитировать Сообщить модератору
 Re: Особенности применения функции ROUND  [new]
Озверин
Member

Откуда: Ростов-на-Дону
Сообщений: 5183
тут - хорошая и быстрая реализация округления http://hiprog.com/index.php?option=com_content&task=view&id=160&Itemid=35
1 фев 19, 13:55    [21799668]     Ответить | Цитировать Сообщить модератору
 Re: Особенности применения функции ROUND  [new]
Joss
Member

Откуда: г. Минск
Сообщений: 4908
Akina
Я уж не говорю о том, что сколько не добавляй, всегда найдётся значение, которое даст неверный результат. Скажем, для наименьшего из предложенных выше 0,0001 такой казус будет, к примеру, со значением 12.644445.

А какова функция округления? До какого знака Вы округляли?
1 фев 19, 13:59    [21799677]     Ответить | Цитировать Сообщить модератору
 Re: Особенности применения функции ROUND  [new]
Akina
Member

Откуда: Зеленоград, Москва, Россия
Сообщений: 19440
Пардон, там опечатка.
Joss
Round(12.65 + 0.0001, 1)
Result: 12.7 (округление вверх)

Round(12.64995 + 0.0001, 1) = 12.7
1 фев 19, 14:36    [21799743]     Ответить | Цитировать Сообщить модератору
 Re: Особенности применения функции ROUND  [new]
Joss
Member

Откуда: г. Минск
Сообщений: 4908
Озверин
тут - хорошая и быстрая реализация округления http://hiprog.com/index.php?option=com_content&task=view&id=160&Itemid=35
По-моему, очень неплохое решение.
1 фев 19, 15:10    [21799793]     Ответить | Цитировать Сообщить модератору
 Re: Особенности применения функции ROUND  [new]
Joss
Member

Откуда: г. Минск
Сообщений: 4908
На всякий случай записал сюда.

Автор - Quick_Yak взято отсюда http://hiprog.com/index.php?option=com_content&task=view&id=160&Itemid=35

'Вызов: Round2 (Value, D) или Round2(Value)
Function Round2(ByVal X As Double, _
Optional ByVal D As Byte = 0) As Double

Dim cur As Currency: cur = 10 ^ D

Round2 = Sgn(X) * Int(Abs(X) * cur + 0.5) / cur

End Function
заменил только
Optional ByVal D As Byte = 2
на
Optional ByVal D As Byte = 0
чтоб соответствовала стандартной.

Сделал проверку для одного знака после запятой.
Дало ошибку в случаях: 12.35, 12.45, 12.85, 12.95
Заменил
Round2 = Sgn(X) * Int(Abs(X) * cur + 0.5) / cur
на
Round2 = Sgn(X) * Int(Abs(X) * cur + 0.55) / cur
В случае: 12.05, 12.15, 12,25, 12.35, 12.45, 12.55, 12.65, 12.75, 12.85, 12.95 отработало правильно
12.1, 12.2, 12.3, 12.4, 12.5, 12.6, 12.7, 12.8, 12.9, 13.0

А вот для 12.049, 12.149, 12,249 ... дают ошибку на 0.1
12.1, 12.2, 12.3, ...

Для 12.039, 12.139, 12,239 ... результаты верны
12.0, 12.1, 12.2

Теперь заменил
Round2 = Sgn(X) * Int(Abs(X) * cur + 0.5) / cur
на
Round2 = Sgn(X) * Int(Abs(X) * cur + 0.51) / cur

Ошибок для данных типа 12.049, 12.149 ошибок нет зато для 12.0499, 12.1499 опят на 0.1 больше чем по правилам округления. Продолжаю экспериментировать.
4 фев 19, 13:03    [21801205]     Ответить | Цитировать Сообщить модератору
 Re: Особенности применения функции ROUND  [new]
AndrF
Member

Откуда:
Сообщений: 2094
ПЕНСИОНЕРКА
эта функция врала всегда, даже в древнем dBASE и foxPRO


Эта функция никогда не врала и не врет.

Просто используется так называемое банковское округление. Используйте его и не ломайте себе голову.
4 фев 19, 14:05    [21801278]     Ответить | Цитировать Сообщить модератору
 Re: Особенности применения функции ROUND  [new]
ПЕНСИОНЕРКА
Member

Откуда: Владимирская обл
Сообщений: 4597
AndrF
ПЕНСИОНЕРКА
эта функция врала всегда, даже в древнем dBASE и foxPRO


Эта функция никогда не врала и не врет.

Просто используется так называемое банковское округление. Используйте его и не ломайте себе голову.


конечно не врет, только округляло 100.1 до 101
с этого началось мое знакомство с этой функцией --после этого в серьезных расчетах я ей не доверяла
4 фев 19, 14:09    [21801284]     Ответить | Цитировать Сообщить модератору
 Re: Особенности применения функции ROUND  [new]
ПЕНСИОНЕРКА
Member

Откуда: Владимирская обл
Сообщений: 4597
AndrF,

была даже статья в журнале КОМПЬЮТЕР-ПРЕСС, объясняющая причину
советов, как избавиться от этого, в статье не было

перебрали все возможные варианты --всеж расчет зарплаты и не сошлись итоги
4 фев 19, 14:16    [21801291]     Ответить | Цитировать Сообщить модератору
 Re: Особенности применения функции ROUND  [new]
Akina
Member

Откуда: Зеленоград, Москва, Россия
Сообщений: 19440
Посмотришь на этот геморрой - и начинаешь думать, не выполнять ли округление через преобразование в строку...
4 фев 19, 14:17    [21801292]     Ответить | Цитировать Сообщить модератору
 Re: Особенности применения функции ROUND  [new]
ПЕНСИОНЕРКА
Member

Откуда: Владимирская обл
Сообщений: 4597
Akina
Посмотришь на этот геморрой - и начинаешь думать, не выполнять ли округление через преобразование в строку...

почти так и сделали, перебрав round-int-fix-str-format-дробную часть размера поля в таблице.....может и еще были варианты

добавляли довесок к половине последнего разряда, для копеек --сначала 0,5 затем 0,45

зарплату вообще считали в копейках, а только на печати делили на 100
4 фев 19, 14:31    [21801309]     Ответить | Цитировать Сообщить модератору
 Re: Особенности применения функции ROUND  [new]
ПЕНСИОНЕРКА
Member

Откуда: Владимирская обл
Сообщений: 4597
помню, что получили в итоге
val(str(12.125,2))=12.13
val(format(12.125,"0.00"))=12.12
4 фев 19, 14:36    [21801316]     Ответить | Цитировать Сообщить модератору
 Re: Особенности применения функции ROUND  [new]
Joss
Member

Откуда: г. Минск
Сообщений: 4908
AndrF
ПЕНСИОНЕРКА
эта функция врала всегда, даже в древнем dBASE и foxPRO


Эта функция никогда не врала и не врет.

Просто используется так называемое банковское округление. Используйте его и не ломайте себе голову.

Что такое "Банковское округление"

Похоже, программа Access округляет числа неправильно. Как быть?

Вас может удивить то, что Access округляет число 21.985 до 21.98. Если вас учили ок­руглять до большего числа, числа заканчивающиеся цифрой 5, то вы считаете, что ре­зультат должен быть 21.99. Этот способ называют арифметическим округлением. Про­грамма Access не применяет арифметическое округление — она выбирает банковское округление, которое лучше в некоторых случаях.

Разница между арифметическим и банковским округлением заключается в трактовке цифры 5. Поскольку число 21.985 находится точно в середине, между числами 21.98 и 21.99, не просто решить, что с ним делать. При постоянном округлении числа с 5 на кон­це до большего числа вносится систематическое отклонение в итоги и средние значения. Поскольку вы округляете до большего чаще, чем до меньшего, любые итоги или среднее, которые вы вычисляете, получаются чуть больше, чем следовало бы.

Банковское округление решает эту проблему округлением 5 в одних случаях до большего числа, а в других до меньшего, в зависимости от соседней четной или нечетной цифры.

Число 21.985 округляется до меньшего числа 21.98, а число 21.995 — до большего, 22. Это не единственный способ борьбы с систематическим отклонением (можно решать случайным образом, когда округлять, а когда нет), но это общепринятая практика в бух­галтерских расчетах и статистике.
4 фев 19, 14:51    [21801337]     Ответить | Цитировать Сообщить модератору
 Re: Особенности применения функции ROUND  [new]
alecko
Member

Откуда: Башкирия
Сообщений: 551
ПЕНСИОНЕРКА
перебрали все возможные варианты --всеж расчет зарплаты и не сошлись итоги

что помешало fix-ировать з/п и остаток переносить на след расчетный период ?
4 фев 19, 14:53    [21801340]     Ответить | Цитировать Сообщить модератору
 Re: Особенности применения функции ROUND  [new]
ПЕНСИОНЕРКА
Member

Откуда: Владимирская обл
Сообщений: 4597
alecko,

позднее перешли на перенос копеек на следующий месяц, когда ширины талончика стало не хватать на зарплату в тысячах(до деноминации)
4 фев 19, 14:56    [21801345]     Ответить | Цитировать Сообщить модератору
 Re: Особенности применения функции ROUND  [new]
sdku
Member

Откуда: Краснодар
Сообщений: 6259
ПЕНСИОНЕРКА
....конечно не врет, только округляло 100.1 до 101
с этого началось мое знакомство с этой функцией --после этого в серьезных расчетах я ей не доверяла
?round(100.1)
 100 
-никак не могу "познакомится"
(может так происходило не из-за применения Round, а по какой-нибудь другой причине?)
4 фев 19, 16:09    [21801418]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft Access Ответить