Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Round(4.5) = 4, Round(5.5) = 6 [D6]


Ученик ©   (2002-11-06 14:45:00) 

По каким это правилам ?


Ученик   (2002-11-06 17:51:00) [1]

>Андрей Прокофьев © (06.11.02 17:41)
Подходит, но хотелось бы влиять на все Round, которые есть в своем коде, RTL, VCL


Андрей Прокофьев   (2002-11-06 17:41:00) [2]

Ученик © (06.11.02 17:33)
см SimpleRoundTo
или не подходит?


Ученик   (2002-11-06 17:33:00) [3]

>TTCustomDelphiMaster © (06.11.02 15:57)
>Ученик © (06.11.02 16:55)
>Ученик © (06.11.02 16:53)
С флажками нет ничего подходящего :(


Ученик   (2002-11-06 16:55:00) [4]

>Ученик © (06.11.02 16:53)
SetRoundMode :-)


Ученик   (2002-11-06 16:53:00) [5]

>TTCustomDelphiMaster © (06.11.02 15:57)

Спасибо за флажок (начал поиск),

{ Project JEDI Code Library (JCL) }

type
T8087Rounding = (rcNearestOrEven, rcDownInfinity, rcUpInfinity, rcChopOrTruncate);

function Get8087ControlWord: Word; assembler;
asm
{$IFNDEF FPC}
SUB ESP, TYPE WORD
{$ELSE}
SUB ESP, $2
{$ENDIF}
FSTCW [ESP]
FWAIT
POP AX
end;

function Get8087Rounding: T8087Rounding;
begin
Result := T8087Rounding((Get8087ControlWord and $0C00) shr 10);
end;

function Set8087ControlWord(const Control: Word): Word; assembler;
asm
FNCLEX
FSTCW Default8087CW
XCHG Default8087CW, AX
FLDCW Default8087CW
end;

function Set8087Rounding(const Rounding: T8087Rounding): T8087Rounding;
var
CW: Word;
begin
CW := Get8087ControlWord;
Result := T8087Rounding((CW and $0C00) shr 10);
Set8087ControlWord((CW and $F3FF) or (Word(Rounding) shl 10));
end;


TTCustomDelphiMaster   (2002-11-06 15:57:00) [6]

Вот откапал:

DiamondShark © (23.08.02 14:04)
Э, нет. Бухгалтерским называется именно первый метод, т.е. вот такой:


1.5 -> 2
3.5 -> 4
2.5 -> 2
4.5 -> 4


Почему? Обясняю.

Рассмотрим набор чисел


1.0 1.0 0
1.1 1.0 -0.1
1.2 1.0 -0.2
1.3 1.0 -0.3
1.4 1.0 -0.4
1.5 ??? ????
1.6 2.0 +0.4
1.7 2.0 +0.3
1.8 2.0 +0.2
1.9 2.0 +0.1
2.0 2.0 0


Первый столбец -- точное число, второй -- округление, третий -- абсолютная ошибка. Легко заметить, что абсолютная ошибка зависит только от значности округления и не зависит от абсолютной величины числа.

А теперь представим, что нам надо считать сумму большого количества чисел, с распределением близким к равномерному, как обычно происходит на бухгалтерских счетАх.
Как видно, все погрешности (кроме 1.5 !) взаимно компенсируются (распределение равномерное). Если мы будем округлять Х.5 -> (X+1).0 или до (Х-1).0, то будет накапливаться систематическая ошибка.
Давайте прикинем, какого значения она может достичь.
Пусть N -- общее количество чисел.
Распределение близкое к равномерному, поэтому вероятность появления числа вида Х.5 -- 0.1
Абсолютная ошибка -- 0.5
Тогда мат. ожидание абсолютной ошибки суммирования N чисел N * 0.1 * 0.5 = N * 0.05

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

Выход -- внести симметрию в вышеприведенную таблицу. Это и достигается округлением четных и нечетных чисел в разные стороны.

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

Вот пример: сумма чисел


точно | бухгалтерский | арифметический
1.5 2.0 2.0
3.5 4.0 4.0
2.5 2.0 3.0
4.5 4.0 5.0
---- ----- -----
12.0 12.0 14.0


Вопросы есть?

PS
кстати, в математическом сопроцессоре есть флажок, управляющий режимом округления (бухгалтерский или арифметический)


TTCustomDelphiMaster   (2002-11-06 14:53:00) [7]

Вроде уже не раз спрашивали. Правда с местным поиском найти что-то невозможно...

Связано это с финансами. Все что меньше Х,5 идет в один карман, что больше Х,5 в другой. А Х,5 чтобы никого не обидеть округляют так: четные к меньшему, нечетные к большему и все довольны и полный баланс :)


Ученик   (2002-11-06 14:51:00) [8]

>LongIsland © (06.11.02 14:48)
>Андрей Прокофьев © (06.11.02 14:48)
Спасибо

Нашел ссылку на рекомендацию IEEE, кто-нибудь в курсе ?


han_malign   (2002-11-06 14:51:00) [9]

По правилам сопроцессора округляется до ближайшего четного. (Вернее исходя из формата хранения вещественных чисел (Double(5.5)<>11/2)).


LongIsland   (2002-11-06 14:48:00) [10]

Округление до четного - по-моему - бухгалтерия:-)


Андрей Прокофьев   (2002-11-06 14:48:00) [11]

X is a real-type expression. Round returns an Int64 value that is the value of X rounded to the nearest whole number. If X is exactly halfway between two whole numbers, the result is always the even number. This method of rounding is often called “Banker’s Rounding”.

см SimpleRoundTo


Наверх

Титульная страница Поиск, карта сайта Написать письмо