Бухгалтерское округление
Модератор: Модераторы
Бухгалтерское округление
Как выполнить бухгалтерское округление в Lazarus?
Так же, как и в Delphi:
Бухгалтерское - с помощью Round,
Математическое - с помощью Trunc, например так:
Lazarus 0.9.29 FPC 2.5.1 Win32
Добавлено спустя 1 час 1 минуту 30 секунд:
Пример бухгалтерского округления:
Lazarus 0.9.29 FPC 2.5.1 Win32
Бухгалтерское - с помощью Round,
Математическое - с помощью Trunc, например так:
Код: Выделить всё
function RoundDoubleDigit(Value: Double; Digit: Integer): Double;
var
Factor: Double;
begin
Factor := Exp(Digit * Ln(10));
if Value < 0 then
Result := Trunc(Value * Factor - 0.5) / Factor
else
Result := Trunc(Value * Factor + 0.5) / Factor;
end;Lazarus 0.9.29 FPC 2.5.1 Win32
Добавлено спустя 1 час 1 минуту 30 секунд:
Пример бухгалтерского округления:
Код: Выделить всё
function BuhDoubleDigit(Value: Double; Digit: Integer): Double;
var
Factor: Double;
begin
Factor := Exp(Digit * Ln(10));
Value := Value * Factor;
Result := Round(Value) / Factor;
end;Lazarus 0.9.29 FPC 2.5.1 Win32
alex_rain писал(а):BuhDoubleDigit
Не всегда округляет 5 в большую сторону! Как это побороть?
А если использовать тип Currency?
- Nik
- энтузиаст
- Сообщения: 573
- Зарегистрирован: 03.02.2006 23:08:09
- Откуда: Киров
- Контактная информация:
Взято из DelphiWorld:
Когда-то писал похожую функцию, но с ходу не нашёл на свалке старых исходников.
Код: Выделить всё
function RoundCurrency(value: currency): currency;
var
x, y: Double;
begin
x := int(value * 100);
y := Frac(value * 100);
if y >= 0.5 then
x := x + 1;
result := x / 100;
end;
Когда-то писал похожую функцию, но с ходу не нашёл на свалке старых исходников.
Vadim писал(а):А если использовать тип Currency?
В Currency только 4 знака после запятой, а мне нужно 15 знаков и возможность округлить до любого знака.
Добавлено спустя 2 минуты 51 секунду:
Вот:
Код: Выделить всё
function RoundN(X: Double; CountDlim: SmallInt): Double;
var
delim: int64 =1;
cd: Byte;
td: Double;
begin
if CountDlim < 0 then Exit;
if CountDlim > 14 then cd := 15 else cd := CountDlim;
if cd > 0 then delim:= 10**cd;
td := X * delim;
if frac(td) < 0.5 then Result := trunc(td) / delim
else Result := ceil(td) / delim;
end; Но даже при этом раскладе 1.005 (при округлении до 2-х знаков) округляется в меньшую. 1 вместо 1.01
Отредактировал
Добавлено спустя 11 минут 19 секунд:
А после 11 знаков начинается полная ахинея
VirtUX писал(а):а мне нужно 15 знаков
Ого!!! Уважаю...
Не всегда округляет 5 в большую сторону! Как это побороть?
Но даже при этом раскладе 1.005 (при округлении до 2-х знаков) округляется в меньшую. 1 вместо 1.01
Бухгалтерское (банковское) округление работает таким образом:
Все числа, у которых «отбрасываемая» цифра не равна 5, округляются по правилам математического округления.
А другие по следующему правилу:
– если цифра, которая стоит перед цифрой 5, четная, то округление осуществляется в меньшую сторону,
– если цифра, которая стоит перед цифрой 5, нечетная, то округление осуществляется в большую сторону.
Цитата из Википедии:
Банковское округление (англ. banker's rounding) — округление для этого случая происходит к ближайшему чётному. Это позволяет устранить систематическую ошибку округления при суммировании большого количества чисел. То есть, 2,5 → 2, 3,5 → 4.
- Astralis
- новенький
- Сообщения: 45
- Зарегистрирован: 06.06.2007 20:33:05
- Откуда: Tvercity-Annet
- Контактная информация:
Если цель состоит только в избавлении систематической ошибки округления при большом количестве суммирования (и других систематических ошибках), то лучший вариант - использовать рандомное округление
многие алгоритмы динамического программирования, требующие дискретизации используют именно такое округление.
Код: Выделить всё
rndround(x) = x-floor(x)<random ? ceil(x) : floor(x)многие алгоритмы динамического программирования, требующие дискретизации используют именно такое округление.
Лично я, решил не заморачиваться. Т.к. ни Float, ни Double, ни Currency не дают возможности использовать в полной мере многорязрядность. GMP тоже странновато себя ведет. Решил отложить на попозже, чтоб написать свой модуль по работе с БОЛЬШИМИ числами - может через годик, два.
