AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX: База знаний и проекты
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 16.10.2004, 09:23   #41  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Re: Нашедший ошибку
Цитата:
Изначально опубликовано REb
А я как раз человек, который эту ошибку обнаружил! )

....И вот в этом отчете на реальных данных при расчете получалось два числа 9999.999999999999, которые при отображении показывались, действительно как 10000, но при сложении давали тоже 10000 ;(((

Удалось обойти благодоря округлению сумм после умножения на коэфициент.

Теперь аккуратнее отношусь к подобным вещам.
А знаете почему у других подобных ошибок не возникало?

Потому что по рекомендациям разработчиков Аксапты ПЕРЕД записью числа в базу данных необходимо выполнять метод currency::amountMST() или currency::Amount().
Эти методы выполняют округление согласно правилам округления в таблице валют.
Вы просто не следовали рекомендациям.

Вопрос здесь скорее в том, что подобные рекомендации должны быть доступны ВСЕМ разработчикам. Такие рекомендации должны бросаться в глаза в первую очередь...
Старый 16.10.2004, 09:24   #42  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Изначально опубликовано savel
А дело даже не в хвостике.
Точка может стоять в любом месте, и даже её может совсем не быть! Всё единно результат не правильный!
Да, Аксапта хранит вещественные числа в виде 16 цифр.
Как только необходимо выполнять вычисления в 16ой цифрой - возникает ошибка.
Старый 16.10.2004, 14:24   #43  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,941 / 3229 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Цитата:
--------------------------------------------------------------------------------
Изначально опубликовано savel
А дело даже не в хвостике.
Точка может стоять в любом месте, и даже её может совсем не быть! Всё единно результат не правильный!
--------------------------------------------------------------------------------

Muzzy, в том-то и проблема, что десятичная точка может стоять в ЛЮБОМ (!) месте и округлением это, к сожалению, не вылечишь. Кроме того, даже если бы это помогало - необходимо было бы при каждой арифметической операции делать округление а не только перед записью в базу.
Старый 16.10.2004, 14:47   #44  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Изначально опубликовано Logger
Цитата:
--------------------------------------------------------------------------------
Изначально опубликовано savel
А дело даже не в хвостике.
Точка может стоять в любом месте, и даже её может совсем не быть! Всё единно результат не правильный!
--------------------------------------------------------------------------------

Muzzy, в том-то и проблема, что десятичная точка может стоять в ЛЮБОМ (!) месте и округлением это, к сожалению, не вылечишь. Кроме того, даже если бы это помогало - необходимо было бы при каждой арифметической операции делать округление а не только перед записью в базу.
Это я понимаю. Проблема возникает, когда появляется 16 цифра.
Без округления - это очень большие числа.
Поэтому это маловероятно.

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

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

Согласен, что это ошибка и ее надо исправлять.
Но сейчас людям надо быстро найти обходной путь

Еще раз: перед записью в базу обязательно надо вызывать currency::amount или currency::amountMST. Это рекомендация, близкая к стандарту.
Старый 16.10.2004, 15:19   #45  
Lazy_Tiger is offline
Lazy_Tiger
NavAx
Axapta Retail User
1C
NavAx Club
 
610 / 31 (3) +++
Регистрация: 17.12.2001
Адрес: Красноярск
а вот и первый ответ из МБС

"...Спасибо за детальный пример. Проблема уже зарегистрирована ранее в Product Studio для исправления командой SE, #2963. Принята к испавлению как критическая 29.09.2004. Ожидается исправленной в SP4, либо в kernel HF для него.

Возможный обходной путь
"The internal precision on reals in Aptata is 16 digits.
The job below can be used to study what happens when we use all the digits and try to use one more.
If you in the function myRound replaces 0.49 with 0.5 it will actually add one (the other option is to add 0).
And that something like what the kernel does in the round function when if .
If you add 0.49 it works on your 14 digits number.
You COULD call myRound() instead of round() for numbers bigger than 10000000000000. (13 zeros, 14 digits) If you call it for smaller numbers we probably should not use the constant 0.49, but 0.49999…, so just call round() instead.
static void JobTestRound(Args _args)
{
real myReal = 12345678901234.00; // 14 digits
real r;

real myRound(real r1, real r2)
{
real r3 = r1/r2;
real r4;
print "r3:", r3;
r4 = trunc(r3+0.49);
print "r4:", r4;
return r4 * r2;
}

r = round(myReal, 0.01);
print "round: ", r;
r = myRound(myReal, 0.01);
print "myRound:", r;
pause;
}

Данный запрос будет обновлен по мере изменения статуса запроса от группы SE (группы разработки). Попробую добиться выпуска HF для SP3 для ядра ранее выхода SP4, но обещать не могу"

Т.е. проблемка известна, признана критической чуть более двух недель назад.

P.S. Вот такая мысль в голову пришла. А почему клиенты напрямую не допускаются к этой информации? Ну хотя бы в режиме чтения? Ведь пока мы сами такое не словим, мы и знать не будем что бывают ситуации когда 2+2=5. Впрочем равно как и по другим багам... Да хотябы по багам со статусом критичных, блин. Не понимаю я этого режима ЧРЕЗВЫЧАЙНОЙ секретности
__________________
И все они создания природы...
Старый 16.10.2004, 15:37   #46  
REb is offline
REb
Участник
 
6 / 10 (1) +
Регистрация: 03.09.2004
Адрес: Питер
Re: Re: Нашедший ошибку
Цитата:
Изначально опубликовано mazzy


А знаете почему у других подобных ошибок не возникало?

Потому что по рекомендациям разработчиков Аксапты ПЕРЕД записью числа в базу данных необходимо выполнять метод currency::amountMST() или currency::Amount().
Эти методы выполняют округление согласно правилам округления в таблице валют.
Вы просто не следовали рекомендациям.

Так то оно так, но вот если не сохраняю я это число в БД, а умножаю и вывожу пользователю (display метод), ну и накопительный итог тоже сам считаю. Как тут быть?
Старый 16.10.2004, 15:55   #47  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
ну вы как маленькие.
перед любым использованием, перед возвратом из метода вызовите, до того, как показать пользователю вызовите метод округления.

кстати, показывать display метод, который возвращает чистый real - моветон втройне.
display метод должен возвращать тип из EDT.
А там округление выполняется ядром.

Хотя и здесь лучше вызвать currency::amount или currency::amountMST.
Поскольку этим методы выполняют округление так, как настроено в справочнике валют.
Старый 17.10.2004, 09:47   #48  
Alks is offline
Alks
Участник
 
336 / 41 (2) +++
Регистрация: 23.07.2004
Адрес: г. Новокузнецк
Да нет, же, mazzy, речь то о другом.
Ну и пусть вы храните числа в базе в округленном до n знаков после запятой виде.
Это уменьшит число проблем связанных с данным глюком, но ни в коей мере не избавит от них.

Посмотрите на следующий код - числа a и b совершенно целые, НЕ ДРОБНЫЕ И НЕ БОЛЬШИЕ, но ошибка (именно ошибка, а не тривиальная неточность округления в вещественной арифметике) происходит не при сохранении или извлечении из/в базу, а по ходу промежуточных вычислений над совершенно безобидными числами!!!

PHP код:
static void Summ(Args _args)
{
    
real a 1;
    
real b 3;
    
real c b;
    ;
    print 
* (c), " = "c" ?!!!!!";
    
pause;

Вот про то и речь!
(Изначально так и было написано что числа 9999.9999.... получены в результате вычислений, но не извлечены из базы)
Операция деления становится совершенно небезопасной, т.к. может сгенерировать нам периодическую дробь из совершенно нормальных, округленных чисел, которая в свою очередь становится небезопасной при суммировании с другими периодическими дробями!
Это же просто капец какой то.
Старый 17.10.2004, 09:51   #49  
domandr is offline
domandr
Участник
 
190 / 5 (1) +
Регистрация: 10.08.2004
Адрес: Москва
Re: Re: Нашедший ошибку
Цитата:
Изначально опубликовано mazzy

Потому что по рекомендациям разработчиков Аксапты ПЕРЕД записью числа в базу данных необходимо выполнять метод currency::amountMST() или currency::Amount().
Эти методы выполняют округление согласно правилам округления в таблице валют.
А в случае товарных остатков и оборотов (т.е. не денежных) тоже необходимо выполнять данные методы?
Старый 17.10.2004, 10:30   #50  
domandr is offline
domandr
Участник
 
190 / 5 (1) +
Регистрация: 10.08.2004
Адрес: Москва
Цитата:
Изначально опубликовано mazzy
ну вы как маленькие.
перед любым использованием, перед возвратом из метода вызовите, до того, как показать пользователю вызовите метод округления.
А при вычислениях тоже округлять вещественные значения. Ведь давно известно, что Окр(X+Y+Z) != Окр(X) + Окр(Y) + Окр(Z)
Будут новые глюки.
Старый 17.10.2004, 21:51   #51  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Изначально опубликовано Alks
Да нет, же, mazzy, речь то о другом.
Ну и пусть вы храните числа в базе в округленном до n знаков после запятой виде.
Это уменьшит число проблем связанных с данным глюком, но ни в коей мере не избавит от них.

Посмотрите на следующий код - числа a и b совершенно целые, НЕ ДРОБНЫЕ И НЕ БОЛЬШИЕ, но ошибка (именно ошибка, а не тривиальная неточность округления в вещественной арифметике) происходит не при сохранении или извлечении из/в базу, а по ходу промежуточных вычислений над совершенно безобидными числами!!!
Да, я это отлично понимаю.
Баг.

Я хотел бы обратить внимание тех, кто хочет найти решение до выходы СП на сообщение Максима Горбунова

Цитата:
Изначально опубликовано Maxim Gorbunov
Опытным путем установлено, что если сумма цифр в последней позиции больше или равна 15, появляется ошибка. Для остальных значений работает верно.
Alks, сейчас есть два пути.
1. кричать майкрософт масдай. А заодно и Навижин с Дамгаардом.
2. минимизировать вероятность проявления бага.

Я бы хотел понять, что можно сделать для минимизации.
Старый 29.10.2004, 14:03   #52  
vasiliy is offline
vasiliy
Программер
 
288 / 17 (1) ++
Регистрация: 21.10.2004
Адрес: E-burg
Цитата:
Изначально опубликовано Alks
Да нет, же, mazzy, речь то о другом.
Ну и пусть вы храните числа в базе в округленном до n знаков после запятой виде.
Это уменьшит число проблем связанных с данным глюком, но ни в коей мере не избавит от них.

Посмотрите на следующий код - числа a и b совершенно целые, НЕ ДРОБНЫЕ И НЕ БОЛЬШИЕ, но ошибка (именно ошибка, а не тривиальная неточность округления в вещественной арифметике) происходит не при сохранении или извлечении из/в базу, а по ходу промежуточных вычислений над совершенно безобидными числами!!!

PHP код:
static void Summ(Args _args)
{
    
real a 1;
    
real b 3;
    
real c b;
    ;
    print 
* (c), " = "c" ?!!!!!";
    
pause;

Вот про то и речь!
(Изначально так и было написано что числа 9999.9999.... получены в результате вычислений, но не извлечены из базы)
Операция деления становится совершенно небезопасной, т.к. может сгенерировать нам периодическую дробь из совершенно нормальных, округленных чисел, которая в свою очередь становится небезопасной при суммировании с другими периодическими дробями!
Это же просто капец какой то.
А вы не используйте промежуточных переменных и все норм будет
Старый 02.11.2004, 11:56   #53  
SimPai is offline
SimPai
MCTS
MCBMSS
 
105 / 10 (1) +
Регистрация: 22.05.2002
Адрес: Москва
Не то чтоб ошибка...
Вот ещё. Не то, чтоб ошибка, но выглядит забавно:

PHP код:
static void Test(Args _args)
{
    
int i   ;

    
0x7fffffff  ;
    print 
" "i*2  ;
    
pause   ;

__________________
Удачи.
Старый 02.11.2004, 12:33   #54  
belugin is offline
belugin
Участник
Аватар для belugin
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,622 / 2925 (107) +++++++++
Регистрация: 16.01.2004
Записей в блоге: 5
все правильно: 0x7fffffff*2 == 0x7fffffff<<1 == 0xfffffffe == -2
Старый 02.11.2004, 12:48   #55  
SimPai is offline
SimPai
MCTS
MCBMSS
 
105 / 10 (1) +
Регистрация: 22.05.2002
Адрес: Москва
Цитата:
все правильно
Угу.
А так будет ещё забавней:

PHP код:
print " "i*2" "i*3   
__________________
Удачи.
Старый 02.11.2004, 13:30   #56  
belugin is offline
belugin
Участник
Аватар для belugin
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,622 / 2925 (107) +++++++++
Регистрация: 16.01.2004
Записей в блоге: 5
i*3 == i*2+i == -2 + i
Старый 05.11.2004, 07:27   #57  
Lazy_Tiger is offline
Lazy_Tiger
NavAx
Axapta Retail User
1C
NavAx Club
 
610 / 31 (3) +++
Регистрация: 17.12.2001
Адрес: Красноярск
Цитата:
Изначально опубликовано vasiliy
А вы не используйте промежуточных переменных и все норм будет
очень смешно. а еще "прошерстите всю систему на предмет операции деления и навставляйте туда доп. проверок ", потому что некий программер не смог простейшие арифметические операции корректно сделать.
__________________
И все они создания природы...
Теги
баг, математика, округление

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Абстрактный классификатор Maxim Gorbunov DAX: Программирование 52 17.01.2005 13:52
Здравствуйте дети! :) - еще одна ошибка AKIS-Falcon DAX: Программирование 11 20.10.2004 18:28
Просмотр SQL запросов к БД с помощью файла Log Anton Sk. DAX: База знаний и проекты 3 25.01.2002 16:31
Виртуальные поля Oks DAX: Функционал 6 03.01.2002 16:08

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 00:08.