Доброго всем.
Бухгалтерии и прочим захотелось
правильного округления (по правилам математики)
Википедия |
Число округляется до N-ого знака по-разному в зависимости от N+1 знака: Если N+1 знак <5, то N-ый знак не меняется, а N+1 и все последующие обнуляются. Если N+1 знак ≥5, то N-ый знак увеличивается на единицу, а все знаки начиная с N+1 обнуляются. |
а не по правилам
Access |
Round(1.5) = 2
Round(2.5) = 2 |
В результате работы мозга получилась относительно универсальная функция, позволяющая округлять числа с необходимой точностью (как знаки после запятой, так и десятки-сотни и т.п.)
Public Function TrueRound(argument As Double, Optional accuracy As Integer)
' argement - округляемое число
' accuracy - требуемая точность: 1; 2; 3 – десятые, сотые, тысячные; -1; -2; -3 – десятки, сотни, тысячи...
' при отсутствии accuracy округляется до целого
Dim n1 As Long
n1 = Exp(Abs(Nz(accuracy, 0)) * Log(10))
Select Case True
Case Nz(accuracy, 0) > 0
TrueRound = Int(CDbl(argument) * n1) / n1 + IIf(Int(CDbl(argument) * n1) / n1 < CDbl(argument), 1 / n1, 0)
Case Nz(accuracy, 0) < 0
TrueRound = Int(CDbl(argument) / n1) * n1 + IIf(Int(CDbl(argument) / n1) * n1 < CDbl(argument), n1, 0)
Case Else
TrueRound = Int(argument + 0.5)
End Select
End Function
Тестовые примеры |
TrueRound (1.5) = 2
TrueRound (2.5) = 3
TrueRound (1.555, 2) = 1.56
TrueRound (1.565, 2) = 1.57
TrueRound (1555, -1) = 1560
TrueRound (1565, -1) = 1570
TrueRound (-1.5) = -1
TrueRound (-2.5) = -2
TrueRound (-1.555, 2) = -1.55
TrueRound (-1.565, 2) = -1.56
TrueRound (-1555, -1) = -1550
TrueRound (-1565, -1) = -1560 |
При необходимости округления до
бОльшего по модулю в каждом варианте второе слагаемое должно иметь соответствующий округляемому числу знак.
Если есть желание проверить, потестировать, покритиковать, поправить или указать на ошибку - милости прошу, буду только рад.