Форум: "Потрепаться";
Текущий архив: 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