Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Потрепаться";
Текущий архив: 2003.09.04;
Скачать: [xml.tar.bz2];

Вниз

Округление чисел. Неужели ТАК правильно???   Найти похожие ветки 

 
Calm   (2003-08-13 10:31) [0]

Вчера услышал от преподавателя курсов Бух. учета следующее правило округления:
1. 15.746 -> 17.7
2. 15.764 -> 17.8
3. 17.752 -> 17.8
4. 17.252 -> 17.2
5. 17.052 -> 17.0

Было выдано утверждение - Если за последней значащей цифрой стоит 5, то последнюю цифру увеличивают, если она нечетная и уменьшют, если четная.

Первый раз слышу о таком? Четная цифра, нечетная... Неужели я когда-то прогулял какую-то лекцию по вычислительной математике? Мы там много разных округлений изучали, но чтобы такого...
Да и в школе не было такого!

Неужели такое приавло действительно существует???


 
Е-Моё имя   (2003-08-13 10:35) [1]

ты окончательно упал в моих глазах
;))))))


 
Внук   (2003-08-13 10:37) [2]

Это так называемое "бухгалтерское" округление. Имеет место быть.


 
Anatoly Podgoretsky   (2003-08-13 10:42) [3]

4. 17.252 -> 17.2
Это не верно, но всегда можно ввести в рамки закона
Эти правило действуют когда лежит ровно посредине, наприме
3. 17.750 -> 17.8
4. 17.250 -> 17.2


 
Calm   (2003-08-13 10:47) [4]


> Эти правило действуют когда лежит ровно посредине, наприме
>

Но в курсе вышки, выч. мата и около математических науках такого утверждения я не встречал. Я закончил спец. программное обеспечение выч. техники и на малое количество часов математики мы пожаловаться не могли. Я твердо был уверен, что если за последней значащей цифрой стоит 5, то округляется в большую сторону. Даже если ровно посередине (17,250000).
Я не прав?


> Это так называемое "бухгалтерское" округление. Имеет место
> быть.

Это шутка, или серьезно? Если серьезно, то это должно быть прописано в каком-то нормативном документе. В каком?


 
Внук   (2003-08-13 10:51) [5]

>>Это шутка, или серьезно?
Вполне серьезно. То, к чему мы с тобой привыкли - обычное математическое округление. А в бухгалтерских расчетах применяется то, о чем ты пишешь. И в программах соответствующих. А насчет нормативных документов не знаю, я ж не "букгактер".


 
Anatoly Podgoretsky   (2003-08-13 10:51) [6]

Calm © (13.08.03 10:47) [4]
В какой то мере прав, существует много методов округления, нормативные документы есть, много, разные. Это внутреннее дело. Сейчас в основном применяют так называемое "банковское" округление, поскольу оно дает меньшую погрешность на массиве чисел.


 
sniknik   (2003-08-13 10:52) [7]

> Неужели такое приавло действительно существует???
а ты попробуй в дельфях округлить там такое и получиш

RoundTo uses “Banker’s Rounding” to determine how to round values ....

The following examples illustrate the use of RoundTo:
Expression Value
RoundTo(1234567, 3) 1234000
RoundTo(1.234, -2) 1.23
RoundTo(1.235, -2) 1.24
RoundTo(1.245, -2) 1.24


 
Nikolay M.   (2003-08-13 10:53) [8]


> Это так называемое "бухгалтерское" округление.

Есть, стопудово.
Не знаю точной подоплеки, но, возможно, при частой работе такого округления при больших посчетах округления вверх-вниз компенсируют друг друга (их будет примерно поровну) и получается золотая середина :)


 
Calm   (2003-08-13 10:54) [9]


> Это внутреннее дело

Внутренее дело кого? Организации или отрасли?

Если я в своей организации буду применять одно округление, а налоговая другое, то на массиве чисел будет разногласие. Небольшое разногласие, но формально с точки зрения налоговой я окажусь не прав? Штрафы, пеня...


 
Calm   (2003-08-13 11:00) [10]

ну дела...


 
Толик   (2003-08-13 11:04) [11]

Подобное округление принято в бухучете. Соотв., налоговая тоже применяет это округление, так что всё должно сойтись, по крайней мере на бумаге :))


 
DiamondShark   (2003-08-13 11:20) [12]

Ох-хо-хо... Ещё раз.
Предположим, что распределение чисел у нас близко к равномерному случайному. Тогда при "арифметическом" округлении имеем:

Цифра Погрешность
0 0
1 -1
2 -2
3 -3
4 -4
5 +5
6 +4
7 +3
8 +2
9 +1

Как легко заметить, если имеется большой массив чисел, которые потом понадобится суммировать (итого для позиций документа, сальдо по счёту и т.п.), то при "арифметическом" округлении будет накапливаться систематическая погрешность с матожиданием
0.5*10^n * 0.1 * N
где:
n -- десятичный вес разряда, до которого производится округление (до двух знаков n=-2, до целых n=0 и т.д.)
0.1 -- вероятность каждой цифры
N -- число суммируемых чисел в массиве

Для того, чтобы выровнять вероятности погрешностей надо скомпенсировать единственную нескомпенсированную (см. таблицу выше) погрешность +5. Для этого она искусственно разбивается на две равновероятные +5 -5 в зависимости от чётности предыдущей цифры.

Кстати, в слове состояния FPU есть флажок, контролирующий режим округления (арифметический/бухгалтерский).


 
Anatoly Podgoretsky   (2003-08-13 11:42) [13]

Calm © (13.08.03 10:54) [9]
Внутреннее дело двух сторон, они должны действовать по едниным правилам, по каким не важно


 
uw   (2003-08-13 12:11) [14]

При арифметических вычислениях дело не заканчивается тем разрядом, который мы округляем. При равномерном случайном распределении за цифрой 0 идет в среднем 0.5. Поэтому:

0 -0.5
1 -1.5
2 -2.5
3 -3.5
4 -4.5
5 +4.5
6 +3.5
7 +2.5
8 +1.5
9 +0.5

Если мы это все просуммируем, то получим как раз 0.


 
Dimka Maslov   (2003-08-13 12:14) [15]

На самом деле такое окгугление правильнее, если потом придётся суммировать резльтаты окргуления, если действовать общепринятым способом (округлять в большую сторону если последняя цифра 5) даст большую погрешность в сумме чисел. Для минимизации погрешности суммы и применяется такое вот округление. Оно используется не только в бухгалтерских расчётах, но и напрмер в геодезических при обработке результатов инструментальной съёмки.


 
uw   (2003-08-13 12:26) [16]

>Dimka Maslov © (13.08.03 12:14) [15]

Как это может быть? Отрезок от 0 до 5-d в точности равен отрезку от 5 до 10-d, где d определяется разрядностью машины. Сдается мне, что рассматриваемый хитрый алгоритм - предрассудок бухгалтеров-троечников.


 
Dimka Maslov   (2003-08-13 12:36) [17]

>uw
Вероятность того, что перед пятёркой окажется чётное или нечётное число примерно одинаковая. Если же всё время округлять в большую сторону, набегающая погрешность будет только увеличиваться, а при таком подходе, погешность будет то складываться, то вычитаться, что в итоге должно её минимизировать. А если это не делать, то это черевать либо финансовыми потерями, либо невозможностью нормальной эксплуатации или вообще обрушением строящегося сооружения. А рассматриваемы хитрый аглоритм это не предрассудок бухгалтеров троечников, а методика, предложенная для статистических рассчётов самим Гауссом (если тебе это имя о чём-то говорит)


 
uw   (2003-08-13 12:41) [18]

>Dimka Maslov © (13.08.03 12:36) [17]

Ты меня Гауссом не пугай. Ты мне пальцем покажи, где ошибка в посте uw © (13.08.03 12:11) [14], и я скажу тебе спасибо.


 
nikkie   (2003-08-13 12:41) [19]

>uw
ты рассуждаешь как математик. а у бухгалтеров все числа имеют конечное число знаков. если отбрасывается 1 цифра, то DS дал тебе табличку. если отбрасывается 2 цифры, то погрешность получается ближе к твоей, но все же не 0.5, а 0.45 = (сумма от 0 до 9)/10. поэтому при суммировании будет средняя погрешность будет ненулевой. чем больше знаков было в исходных числах, тем меньше эта погрешность, но никогда не ноль. бухгалтерское правило делает ее нулем при любом количестве отбрасываемых цифр.


 
uw   (2003-08-13 12:49) [20]

>nikkie © (13.08.03 12:41) [19]

Я не понимаю, от чего отбрасывается. Предположим, мы взвесили колбасу, посчитали, получили 32.1234567... руб. Округляем. Вместо истинного значения с периодом получаем 32.12 руб. И что?


 
nikkie   (2003-08-13 13:00) [21]

... - не получается никак.
цена колбасы - 2 знака после запятой.
весы - 4 знака после запятой.
итого - 6, округляем до 2-х.
сделай оценку погрешнсти в такой ситуации.


 
nikkie   (2003-08-13 13:01) [22]

сорри, весы - 3 знака. итого - 5.


 
uw   (2003-08-13 13:06) [23]

>Dimka Maslov © (13.08.03 12:36) [17]
>Если же всё время округлять в большую сторону, набегающая погрешность будет только увеличиваться.

Школьный алгоритм округления не все время округляет в большую сторону. Цифры 0,1,2,3,4 он округляет в меньшую сторону, а цифры 5,6,7,8,9 - в большую. И тех, и других ровно по пять. Если у Гаусса другие соображения, покажи мне их, я не нашел в Интернете.


 
Dimka Maslov   (2003-08-13 13:06) [24]

>uw
Пример:
1.245 + 1.115 = 2.36

Округляем до двух знаков в большую сторону, поскольку последняя цифра 5 получаем:
1.25 + 1.12 = 2.3 7 (имеем погрешность при суммировании)

А теперь округляем по Гауссу:
1.24 + 1.12 = 2.36 (погрешности нет)


 
uw   (2003-08-13 13:18) [25]

Пример:

1.244 + 1.245 = 2.489 = 2.49

По-школьному:
1.24 + 1.25 = 2.49

По Гауссу:
1.24 + 1.24 = 2.48


 
DiamondShark   (2003-08-13 14:57) [26]


> uw © (13.08.03 13:06) [23]


А вот и ошибка.


Цифры 0,1,2,3,4 он округляет в меньшую сторону, а цифры 5,6,7,8,9 - в большую


Цифра 0 вообще никуда не округляется.

Решите примерчик
1.25 + 1.35 + 1.45 + 1.55 = ?

а) точно
б) округляя каждое слагаемое до #.# арифметически
б) округляя каждое слагаемое до #.# по-бухгалтерски

Сравните ответы и сделайте вывод.


 
app   (2003-08-13 14:59) [27]

DiamondShark © (13.08.03 14:57) [26]
влево 4, вправо 5, а распределение нормально


 
uw   (2003-08-13 15:29) [28]

>DiamondShark © (13.08.03 14:57) [26]

Округляем 0 в меньшую сторону, почитай uw © (13.08.03 12:11) [14].

Контрпримерчик я уже приводил (uw © (13.08.03 13:18) [25] ).

Но я еще и помоделировал и увидел, что по-школьному ничуть не хуже:

procedure Test;
var
a, b: Double;
s1, s2: Double;
i: Integer;
begin
s1 := 0; s2 := 0;
Randomize;
a := RoundTo(1.235, -2);
a := RoundTo(1.245, -2);
a := RoundTo(1.255, -2);
a := RoundTo(1.265, -2);
for i := 1 to 1000 do begin
a := Random(10000) / 1000;
b := Random(10000) / 1000;
s1 := s1 + Round((a + b) * 1000) / 1000 -
(Round(a * 100) / 100 + Round(b * 100) / 100);
s2 := s2 + Round((a + b) * 1000) / 1000 - (RoundTo(a, -2) + RoundTo(b, -2));
end;
end;


 
nikkie   (2003-08-13 17:22) [29]

>uw
похоже еще один самолет ;) но с математикой я думаю проще будет разобраться.

давай для простоты рассмотрим арифметическое округление десятичного числа с n знаками после запятой до целого. берем ну очень равномерное распределение распределение, все числа от 0 до 0,99..99:
0,00...00
0,00...01
0,00...02
0,00...03
...
0,49...99 - округляются до 0
0,50...00
0,50...01
...
0,99...99 - округляются до 1

легко видеть, что средняя ошибка округления 5 * 10^(-n)


 
DiamondShark   (2003-08-13 17:38) [30]


> uw © (13.08.03 15:29) [28]

Зачем быть таким упёртым?


> Округляем 0 в меньшую сторону, почитай uw © (13.08.03
> 12:11) [14].

1.20 округляем до одного знака, сколько получим?


> Но я еще и помоделировал и увидел, что по-школьному ничуть
> не хуже:

Ерунду вы намоделировали.

program Project1;
{$APPTYPE CONSOLE}

var
Table: array[word] of double;
i: integer;
S, S1, S2: extended;
begin
randomize;
S := 0;
for i := low(Table) to high(Table) do
begin
Table[i] := Random * 10;
S := S + Table[i]; // это будет точная сумма
end;

Set8087CW($1372); // включаем "бухгалтерское" округление
S1 := 0;
for i := low(Table) to high(Table) do
S1 := S1 + Round(Table[i]);

Set8087CW($1B72); // включаем "школьное" округление
S2 := 0;
for i := low(Table) to high(Table) do
S2 := S2 + Round(Table[i]);

writeln(S:20:0, S1:20:0, S2:20:0);
if S2 <= S1 then writeln("DS должен мне $1000 !!!");

readln;
end.


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


 
uw   (2003-08-14 11:19) [31]

>nikkie © (13.08.03 17:22) [29]

Не очень понял, к чему ты это привел, но это уже и неважно. На самом деле, я твою мысль понял уже после разговора о колбасе. Да и мой контрпример Dimka Maslov © указывал на то, что не все симметрично. Но, с другой стороны, я был убежден в симметричности Round. С DS разговаривать трудно: ты ему говоришь, что округление числа 1.209999 до первого десятичного знака происходит в меньшую сторону, а он делает вид, что округления бывают только с последними цифрами и приводит пример 1.20 и обзывает тебя упертым ослом. Но выяснилось, что и с ним можно разговаривать, если привести пример, все равно какой. После его примера я с изумлением обнаружил, что и Round по умолчанию тоже использует «банковский» алгоритм, и я пришел к внутреннему согласию. Так что, все методы хороши – и твой, мягкий, и буйно агрессивный метод DS. Единственный метод, который здесь ни к чему не приводит – это метод ссылки на имя Остроградского или даже Гаусса: они ничего не знали про реализацию Round.


 
nikkie   (2003-08-14 13:00) [32]

>uw
>На самом деле, я твою мысль понял уже после разговора о колбасе.
дык, если б ты об этом сказал, я бы и не встревал... ;)


 
DiamondShark   (2003-08-14 13:03) [33]

Представим число X в виде
X = A + a*10^(n+1) + b*10^n + R, где:
A >= 10^(n+1)
a, b in {0..9}
R < 10^n
n = ...-2, -1, 0, 1, 2... вес отбрасываемого разряда

Тогда округлённое число X" будет получено в виде
X" = A + a"*10^(n+1),
а правила округления описывают получение a".
Для "школьного" округления
a" = a при b < 5
a" = a+1 при b >=5

Погрешность
d = X - X" = (A + a*10^(n+1) + b*10^n + R) - (A + a"*10^(n+1)) = (a-a")*10^(n+1) + b*10^n + R
d = b*10^n + R при b < 5
d = -1*10^(n+1) + b*10^n + R = -1*(10-b)*10^n + R при b >= 5

Возможные диапазоны погрешностей:
b диапазон
-----------------------------
0 [0; 10^(n-1)]
1 (10^(n-1); 10^n]
2 (10^n; 2*10^n)
3 (2*10^n; 3*10^n]
4 (3*10^n; 4*10^n]
5 [-5*10^n; -4*10^n)
6 [-4*10^n; -3*10^n)
7 [-3*10^n; -2*10^n)
8 [-2^10^n; -10^n)
9 [-10^n; 0)

У кого-то ещё остались какие-то вопросы?

Специально для uw
Вопрос с округлением нуля, полагаю, решён? Диапазон погрешностей округленя девятки, как легко видеть, перекравает диапазон округления нуля и единицы. А диапазон пятёрки остаётся единственным не имеющим симметричного диапазона другого знака.
Со мной трудно разговаривать с позиций "я был глубоко убеждён", но чрезвычайно легко, как вы верно заметили, говорить доказательно.

ЗЫ
Номер сообщения, где употредляется слово "осёл", надеюсь, не составит труда указать?


 
uw   (2003-08-14 13:38) [34]

>DiamondShark © (14.08.03 13:03) [33]
>Номер сообщения, где употредляется слово "осёл", надеюсь, не составит труда указать?

DiamondShark © (14.08.03 13:03) [33] :)


 
Anatoly Podgoretsky   (2003-08-14 13:39) [35]

Удалено модератором
Примечание: Личная переписка


 
uw   (2003-08-14 16:04) [36]

>DiamondShark © (14.08.03 13:03) [33]

Объясни мне только одно: почему

Возможные диапазоны погрешностей:
b диапазон
-----------------------------
0 [0; 10^(n-1)]

если d = b*10^n + R при b < 5, а R < 10^n?


 
nikkie   (2003-08-14 16:10) [37]

>Объясни мне только одно: почему
а это чтобы ответ какой надо получить :)
если делать по правде, то получится
b диапазон
-----------------------------
0 [0; 10^n)
1 [10^n; 2*10^n)
2 [2*10^n; 3*10^n)
3 [3*10^n; 4*10^n)
4 [4*10^n; 5*10^n)
5 [-5*10^n; -4*10^n)
6 [-4*10^n; -3*10^n)
7 [-3*10^n; -2*10^n)
8 [-2^10^n; -10^n)
9 [-10^n; 0)
в среднем 0. и останутся еще вопросы... :))


 
uw   (2003-08-14 16:13) [38]

>nikkie © (14.08.03 16:10) [37]

Я побоялся так конкретно (:


 
DiamondShark   (2003-08-14 16:52) [39]


> uw © (14.08.03 16:04) [36]

Ай, как нехорошо получилось...
0 [0; 10^n)
1 [10^n; 2*10^n)
2 [210^n; 3*10^n)
3 [3*10^n; 4*10^n]
4 [4*10^n; 5*10^n]

Хуманум эраре эст. Но это уже не важно.
Елки-палки. Вы мне совсем мозги запудрили.

round(2.5) = 2
round(2.500000000000000001) = 3

"Бухгалтерское" правило применяется не просто если b=5 (в ранее введённых обозначениях), а ещё если R=0. А для случая R=0 диапазоны погрешностей вырождаются в числа, я уже эту табличку приводил:
b d
---------------------
0 +0
1 +1*10^n
2 +2*10^n
3 +3*10^n
4 +4*10^n
5 -5*10^n
6 -4*10^n
7 -3*10^n
8 -2*10^n
9 -1*10^n


 
uw   (2003-08-14 17:07) [40]

>DiamondShark © (14.08.03 16:52) [39]

Все ОК. Теперь мне можно идти в булгахтеры... но в маленькие :)



Страницы: 1 2 вся ветка

Форум: "Потрепаться";
Текущий архив: 2003.09.04;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.56 MB
Время: 0.016 c
1-10692
lww
2003-08-20 10:30
2003.09.04
Как написать dll для 1С?


14-10877
^Некто^
2003-08-13 19:16
2003.09.04
MSBlast


3-10564
denick
2003-08-15 11:04
2003.09.04
Вопрос по Rave5.


1-10702
Opera
2003-08-20 17:13
2003.09.04
Массив


14-10879
Скорбящий
2003-08-14 17:37
2003.09.04
Развёрнутый nslookup для айпишника





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский