Математическое округление

bootty
Дата: 22.02.2008 10:45:49
Доброго всем.

Бухгалтерии и прочим захотелось правильного округления (по правилам математики)
Википедия
Число округляется до 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

При необходимости округления до бОльшего по модулю в каждом варианте второе слагаемое должно иметь соответствующий округляемому числу знак.

Если есть желание проверить, потестировать, покритиковать, поправить или указать на ошибку - милости прошу, буду только рад.
Чумаков А.
Дата: 22.02.2008 11:05:56
Я вот такой вариант функции использую:

Function Round(Number As Double, Factor As Integer, RI As Variant) As Double
'----------------- Функция окургления ------------------------
'Number - округляемое число
'Facrot - точность
'RI - способ округления

On Error GoTo Err_Round

  Select Case RI
    Case True
   '--------------------- Обычное откидывание лишних знаков 
        Round = (Int(Number / 10 ^ Factor)) * 10 ^ Factor
    Case False
   '--------------------- Округление по правилам математики
        Round = (Int(Number / 10 ^ Factor + 0.5)) * 10 ^ Factor
    End Select

Exit_Round:
    Exit Function

Err_Round:
    MsgBox Err.Description
    Resume Exit_Round

End Function
Polev
Дата: 22.02.2008 11:19:32
Чумаков А.
Я вот такой вариант функции использую:

Ничего не перепутал?
Прямо используешь?
sdfgsdfgsdf
Дата: 22.02.2008 11:20:07
/topic/337273&hl=%ee%ea%f0%f3%e3%eb%e5%ed%e8%e5
Чумаков А.
Дата: 22.02.2008 12:56:27
2 Polev:

Да, а в чем ирония ?
Проверяющий
Дата: 22.02.2008 14:46:42
?TrueRound (1.554, 2)
1,56
ratboy
Дата: 22.02.2008 21:14:13
Бамблю па тецки!!!

Public Function Okrug(a)
Dim b As String
b = Round(a / 10, 0)
If a - b >= 5 Then
a = b * 10
Else
a = b + 10
End If
End Function
bootty
Дата: 20.03.2008 13:28:56
Проверяющий
?TrueRound (1.554, 2)
1,56

Согласен, был неправ, вспылил :)

Выбросил из головы эту фигню и пользуюсь модифицированной версией от Чумакова (см. выше), за что ему респект.
sdfgsdfgsdf
Дата: 20.03.2008 13:30:55
bootty
Дата: 20.03.2008 14:07:38
sdfgsdfgsdf
ЗДЕСЬ ВСЁ !

Уважаемый, благодарю нижайше, тему видел и в первый раз, но всё не нужно, чесслово.. :)
Понадобится - помню где взять ;)