(Новая страница: «Банковское округление») |
|||
Строка 1: | Строка 1: | ||
− | + | == Бухгалтерское (банковское) округление == | |
+ | При вычислении значений с помощью деления (например, НДС) получаются копейки, которые при последующем суммировании и округлении дают интересный эффект - сумма НДС по нескольким позициям может не равняться суммарному значению НДС, рассчитанному на основе общей суммы. | ||
+ | |||
+ | Для борьбы с этой проблемой применяется «бухгалтерское округлении», или, как его называют за рубежом, банковское округление («bank rounding»). | ||
+ | |||
+ | Алгоритм следующий: | ||
+ | |||
+ | - если тысячные доли рубля меньше 5, то тысячные просто отбрасываются; | ||
+ | |||
+ | - если тысячные доли рубля равны 5, а количество сотых четное, то тысячные просто отбрасываются; | ||
+ | |||
+ | - в остальных случаях округляем вверх до сотых. | ||
+ | |||
+ | Примеры: | ||
+ | |||
+ | 0.565335, // bank: 4.56, math: 4.57 | ||
+ | |||
+ | 0.565783, // bank: 34.56, math: 34.57 | ||
+ | |||
+ | 0.355532, // bank: 56.36, math: 56.36 | ||
+ | |||
+ | 0.4557642, // bank: 9.45, math: 9.45 | ||
+ | |||
+ | 0.345643, // bank: 10.34, math: 10.35 | ||
+ | |||
+ | 0.235345, // bank: 7.24, math: 7.24 | ||
+ | |||
+ | 0.285456, // bank: 9.28, math: 9.29 | ||
+ | |||
+ | 0.225, // bank: 3.22, math: 3.23 | ||
+ | |||
+ | 0.25527, // bank: 10.26, math: 10.26 | ||
+ | |||
+ | 0.41525, // bank: 11.42, math: 11.42 | ||
+ | |||
+ | 0.105, // bank: 0.10, math: 0.11 | ||
+ | |||
+ | 0.115, // bank: 0.12, math 0.12 | ||
+ | |||
+ | Такой подход не снимает проблему округления полностью, а только значительно '''''сокращает вероятность накопления ошибки''''' за счет того, что количество «четных» и «нечетных» сумм статистически примерно одинаково. На практике такой точности вполне достаточно. | ||
+ | |||
+ | Этот алгоритм часто используется при расчетах в финансовых системах - 1С, Комтет. | ||
+ | |||
+ | Пример реализации функции на php: | ||
+ | |||
+ | function bank_round ($val) | ||
+ | |||
+ | { | ||
+ | |||
+ | $tmp = intval (abs ($val) * 100); | ||
+ | |||
+ | if ($tmp % 2 != 0) $tmp +=1; | ||
+ | |||
+ | if ($val < 0) $tmp = 0 — $tmp; | ||
+ | |||
+ | return $tmp / 100; | ||
+ | |||
+ | } | ||
+ | <br /> |
Версия 11:26, 2 ноября 2022
Бухгалтерское (банковское) округление
При вычислении значений с помощью деления (например, НДС) получаются копейки, которые при последующем суммировании и округлении дают интересный эффект - сумма НДС по нескольким позициям может не равняться суммарному значению НДС, рассчитанному на основе общей суммы.
Для борьбы с этой проблемой применяется «бухгалтерское округлении», или, как его называют за рубежом, банковское округление («bank rounding»).
Алгоритм следующий:
- если тысячные доли рубля меньше 5, то тысячные просто отбрасываются;
- если тысячные доли рубля равны 5, а количество сотых четное, то тысячные просто отбрасываются;
- в остальных случаях округляем вверх до сотых.
Примеры:
0.565335, // bank: 4.56, math: 4.57
0.565783, // bank: 34.56, math: 34.57
0.355532, // bank: 56.36, math: 56.36
0.4557642, // bank: 9.45, math: 9.45
0.345643, // bank: 10.34, math: 10.35
0.235345, // bank: 7.24, math: 7.24
0.285456, // bank: 9.28, math: 9.29
0.225, // bank: 3.22, math: 3.23
0.25527, // bank: 10.26, math: 10.26
0.41525, // bank: 11.42, math: 11.42
0.105, // bank: 0.10, math: 0.11
0.115, // bank: 0.12, math 0.12
Такой подход не снимает проблему округления полностью, а только значительно сокращает вероятность накопления ошибки за счет того, что количество «четных» и «нечетных» сумм статистически примерно одинаково. На практике такой точности вполне достаточно.
Этот алгоритм часто используется при расчетах в финансовых системах - 1С, Комтет.
Пример реализации функции на php:
function bank_round ($val)
{
$tmp = intval (abs ($val) * 100);
if ($tmp % 2 != 0) $tmp +=1;
if ($val < 0) $tmp = 0 — $tmp;
return $tmp / 100;
}