Караул !!!

Clarion, Clarion 7

Модератор: Дед Пахом

Правила форума
При написании вопроса или обсуждении проблемы, не забывайте указывать версию Clarion который Вы используете.
А так же пользуйтесь спец. тегами при вставке исходников!!!
Ответить
Гость

Сообщение Гость »

Всегда считал что при присваивании арифметического выражения в Decimal результат округляется и вдруг

b decimal(11,2)

b = a*c/f......
stop(b&a*c/f......)

получаю stop
1425.42 1425.425

Причем только для результатов с 5 в третьем разряде округления до большего не происходит

С5 ШВС
Удачи!
==========================
http://www.fordm.ru
Алексей И. Латухин

(Добавление)

А откуда такая уверенность что a*c/f=1425.425 ????
может 1425.4249999999.......

в приведенном примере мало информации.
типы a,c,f не указаны.

--
С уважением,
Дмитрий Осипов mailto:Dima_Osipov@km.ru

Hi,

Если у тебя в a*c/f нет DECIMAL или есть не LONG и не DECIMAL, то работать будет не BCD библиотека, а обычные real операции. В результате получится REAL и real(1425.425) может оказаться меньше, чем 1425425/1000.

WBR, Nick Tsigouro. MailTo:Nick@arsis.ru

(Добавление)

Вырезка в студию

Код: Выделить всё

 
qu_det               group,PRE(qut)
.....
cena_out             DECIMAL(11,2)
....
   end
d_nkl:cena           DECIMAL(11,2)
lk:nalog_nds         DECIMAL(9,2)
lk:nds               DECIMAL(9,2)
lk:sum_rsh           DECIMAL(11,2)
lk:sum_nkl_o_nds     DECIMAL(11,2)
lk:nalog_sale        DECIMAL(11,2)
 
..........
 
 
   qut:cena_out = d_nkl:CENA / (1 + lk:nalog_sale) * (1/(1 + lk:nds) + lk:nalog_sale) * (lk:sum_nkl_o_nds + lk:sum_rsh) / lk:sum_nkl_o_nds
 
   stop(qut:cena_out&'!'&d_nkl:CENA / (1 + lk:nalog_sale) * (1/(1 + lk:nds) + lk:nalog_sale) * (lk:sum_nkl_o_nds + lk:sum_rsh) / lk:sum_nkl_o_nds)


Удачи!
==========================
http://www.fordm.ru
Алексей И. Латухин

А числа сами подберете, чтобы получить
stop
1425.42 1425.425

:lol:

--
С уважением,
Дмитрий Осипов
Написал: ClaList(2)
Гость

Сообщение Гость »

Код: Выделить всё

                  PROGRAM

                  MAP
                  END
qu_det               group,PRE(qut)
cena_out               DECIMAL(11,2)
            end
d_nkl:cena             DECIMAL(11,2)
lk:nalog_nds         DECIMAL(9,2)
lk:nds               DECIMAL(9,2)
lk:sum_rsh           DECIMAL(11,2)
lk:sum_nkl_o_nds     DECIMAL(11,2)
lk:nalog_sale        DECIMAL(11,2)

   code
   d_nkl:CENA = 34.41
   lk:nalog_sale = 0
   lk:nds = 0.2
   lk:sum_nkl_o_nds = 1183332.66
   lk:sum_rsh = 0

  qut:cena_out = d_nkl:CENA / (1 + lk:nalog_sale) * (1/(1 + lk:nds) + lk:nalog_sale) * (lk:sum_nkl_o_nds + lk:sum_rsh) / lk:sum_nkl_o_nds

       stop(qut:cena_out       !
      &'!'&d_nkl:CENA / (1 + lk:nalog_sale) * (1/(1 + lk:nds) + lk:nalog_sale) * (lk:sum_nkl_o_nds + lk:sum_rsh) / lk:sum_nkl_o_nds  !
      &'!'&d_nkl:CENA&'!'&lk:nalog_sale&'!'&lk:nds&'!'&lk:sum_nkl_o_nds)
Удачи!
==========================
http://www.fordm.ru
Алексей И. Латухин

(Добавление)

Ну, посмотрел отладчиком.

в 1-м случае промежуточный результат в BCD математике получается
1425.424999999999999999999999999...... (31 знак всего)

при присвоении промежуточного результата выполняются действия над десятичным числом по математике округление даст 1425.42

во 2-м случае при прицеплении результата в строку это число преобразуется в real и получается 1425.425

Так-что сосчитано правильно, а вот показано в операторе STOP неправильно

--
С уважением,
Дмитрий Осипов

А я считаю, что виноват автор, т.к. при вычислении значения для уменьшения
погрешности необходимо сначала выполнять умножение и в конце деление...
Преобразовав исходное выражение
qut:cena_out = d_nkl:CENA * (1/(1 + lk:nds) + lk:nalog_sale) *
(lk:sum_nkl_o_nds + lk:sum_rsh) / lk:sum_nkl_o_nds / (1 + lk:nalog_sale)
в следующее
qut:cena_out = d_nkl:CENA * (1 + (1 + lk:nds) * lk:nalog_sale) *
(lk:sum_nkl_o_nds + lk:sum_rsh) / lk:sum_nkl_o_nds / (1 + lk:nalog_sale) /(1
+ lk:nds)
получим ПРАВИЛЬНЫЙ результат

С уважением, Звигинцев Михаил.
Написал: ClaList(2)
Гость

Сообщение Гость »

Hi,

А я думаю, что что-то не так с постановкой задачи, если из-за погрешности в 1E-27 люди "Караул!!" кричат.

WBR, Nick Tsigouro. MailTo:Nick@arsis.ru
Написал: ClaList(2)
Гость

Сообщение Гость »

Большое спасибо всем откликнувшимся и напомнившим старые добрые правила операций о которых порой забываешь в угоду читабельности формул.

PS: на 1Е-27 в накладной на сумму 3500000 с большим количеством дешевых з/ч погрешность
составила 1739руб - радость бухгалтерии превышала все границы


Удачи!
==========================
http://www.fordm.ru
Алексей И. Латухин

Самый простой способ избежать погрешностей и не очень задумываться над порядком вычислений - это взять за правило использовать при присвоении decimal переменной округления до точности +1 десятичный знак.

Код: Выделить всё

qut:cena_out = round(d_nkl:CENA / (1 + lk:nalog_sale) * (1/(1 + lk:nds) !
                     + lk:nalog_sale) * (lk:sum_nkl_o_nds + lk:sum_rsh) !
                      / lk:sum_nkl_o_nds,0.001)
--
С уважением,
Дмитрий Осипов mailto:Dima_Osipov@km.ru

(Добавление)

Я пару лет назад бодался с бухгалтером из-за артефактов в счёт-фактуре.И мы сошлись вот на чём. Цена без НДС и цена с НДС должна выражаться в целых копейках. И налог с продаж в них же. А отсюда уже надо плясать - сначала вычислить эти цены, а уже потом ...

---------------------------------------
C уважением,
Юрий Философов,
Главный программист
Корпорация "Диполь", Саратов
E-mail yufil@tacis-dipol.ru (служ)
yufil@mail.ru (дом)
ICQ#75924439
Написал: ClaList(2)
Гость

Сообщение Гость »

И еще понять, что НДС от суммы не равен сумме НДС-ов, несмотря на то, что очень хочется.

WBR, Nick Tsigouro. MailTo:Nick@arsis.ru

Увы, это так... Но в накладной могут быть товары, облагаемые разными НДС. И понятие НДС от суммы - бессмысленно.

---------------------------------------
C уважением,
Юрий Философов

Мы ( в Сбербанке) с похожей проблемой столкнулись при деноминации. Делаем деноминацию счетов, считаем деноминированный балланс и, о ужас, он не сходится со старым не деноминированным. Причем не схоится достаточно ощутимо - счетов много. В масштабе Москвы десятки, если не сотни, миллионов.
Помню тогда вышли из положения тем, что делали округление не по правилам математики, а "по жизни" ;) Написали специальную прогу, которая округляла лицевики так, чтобы сошлись и балансовые счета.

WBR, Nick Tsigouro

(Добавление)
погрешность составила 1739руб - радость бухгалтерии превышала все границы
Погрешность чего и по сравнению с чем? И как это 1Е-27 * 3500000 дает 1739 - это если допустить невероятное, что все погрешности в одну сторону работают?
А я думаю, что что-то не так с постановкой задачи.
Или с расчетной схемой, или пониманием, что такое погрешность.

WBR, Nick Tsigouro

Элементарно, Ватсон.
Я с таким сталкивался. Объясняю:

173900 предметов по 20 руб.
Считается НДС (или что-то-там-еще) по каждому предмету.
Погрешность округления до коп. составляет 1 коп.
Потом НДС (или что-то-там-еще) суммируется. Общая погрешность итога по сравнению с НДС (или чем-то-там-еще) полученным от полной суммы СРАЗУ и составит эти 173900 руб. И ничего с эти не поделаешь. Единственный выход (и ЕДИНСТВЕННО ПРАВИЛЬНЫЙ) - итоги считать от итогов.

Igor Gubin <igor@quantor.com>

Это действительно элементарно, но речь шла не о 1 коп, а о 1Е-27. Собственно именно эта погрешность влияла в представленном примере на округление. Но я сто пудов уверен, что если бы этой погрешности не было, проблема осталась бы. Дело тут не в погрешности выполнеия округления и не в порядке проведения операций.

WBR, Nick Tsigouro
Написал: ClaList(2)
Ответить