ZSN1 0 20 августа, 2015 Опубликовано 20 августа, 2015 · Жалоба Вычисляю sin табличным методом (LPC2478 в среде Keil 4.23) кусок кода .... #define Tabl_acos 0x80000000 ... ... double tsin (double arg) { double argout; unsigned int *adr; adr = (unsigned int *)((unsigned int)Tabl_sin + (unsigned int)(fabs(arg)*400)); argout = *(double *)adr; return (argout); } Указатель adr при вычислении имеет совершенно фантастическое значение ! А в коде ниже (unsigned int)fabs(arg)*400 работает правильно, но теряется точность, поскольку приведение к uint происходит до умножения на 400. .... #define Tabl_acos 0x80000000 ... ... double tsin (double arg) { double argout; unsigned int *adr; adr = (unsigned int *)((unsigned int)Tabl_sin + (unsigned int)fabs(arg)*400); argout = *(double *)adr; return (argout); } Пробовал разные ключи компилятора - не помогает Заметил, что ошибка возникает, когда значение arg*400 превышает 255. Глюк компилятора? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 20 августа, 2015 Опубликовано 20 августа, 2015 · Жалоба Указатель adr при вычислении имеет совершенно фантастическое значение ! "Фантастическое значение"? А это хорошо или плохо? Если есть сомнения в правильности вычислений, разбейте вычисления на элементарные операции и контролируйте результаты на каждом шагу. К тому же у вас как-то подозрительно вычисляется адрес. Он ведь должен быть кратен 8 (указатель на double). При этом совсем нигде не видно, где эта кратность обеспечивается. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 1 20 августа, 2015 Опубликовано 20 августа, 2015 · Жалоба Глюк компилятора? Нет. 400ULL Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 20 августа, 2015 Опубликовано 20 августа, 2015 · Жалоба 400ULL Ага, щас. Вообще-то 400 перед умножением автоматически приводится к double. Так что ULL ничего не изменит. Скорее уж 400.0, чтобы убрать неявное приведение типа. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 1 20 августа, 2015 Опубликовано 20 августа, 2015 · Жалоба Ага, щас. Вообще-то 400 перед умножением автоматически приводится к double. Так что ULL ничего не изменит. Скорее уж 400.0, чтобы убрать неявное приведение типа. Не обратил внимание, что там double. Да, 400.0 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 20 августа, 2015 Опубликовано 20 августа, 2015 · Жалоба Не обратил внимание, что там double. Да, 400.0 Только это всё равно ничего не изменит. У меня есть версия. Возможно, стек не выравнен по границе 8 байт, и из-за этого не работает умножение double*double. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ZSN1 0 20 августа, 2015 Опубликовано 20 августа, 2015 (изменено) · Жалоба Сделал втупую value = arccos (0); // result = 90 value = arccos (0.465); // result = 62.289 value = arccos (0.5); // result = 60 value = arccos (0.563); // result = -4967.265 (incorrect!) value = arccos (0.564); // result = -4967.265 (incorrect!) value = arccos (0.565); // result = -4967.265 (incorrect!) value = arccos (0.566); // result = 0 (incorrect!) value = arccos (0.567); // result = -4967.265 (incorrect!) value = arccos (0.568); // result = -4967.265 (incorrect!) value = arccos (0.569); // result = 0 (incorrect!) value = arccos (0.57); // result = 0 (incorrect!) value = arccos (0.58); // result = 54.549 value = arccos (0.59); // result = 53.842 value = arccos (1); // result = 0 результат поставил вообще в тупик .... таблицу проверял 100 раз выводил на экран значения от 0.5 до 0.6 Возможно в других диапазонах тоже самое Только это всё равно ничего не изменит. У меня есть версия. Возможно, стек не выравнен по границе 8 байт, и из-за этого не работает умножение double*double. А как стек выровнять? Добавить __align(32)? Изменено 20 августа, 2015 пользователем ZSN1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Obam 37 20 августа, 2015 Опубликовано 20 августа, 2015 · Жалоба А как стек выровнять? Добавить __align(32)? Чёй-то 32? С какой радости? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ZSN1 0 20 августа, 2015 Опубликовано 20 августа, 2015 (изменено) · Жалоба Таблица зашита во внешнюю flash /* const double __at(0x80000000) Tabl_acos[400] = { 9.00000000000000E+0001, 8.99942704220391E+0001, 8.99885408440210E+0001, 8.99828112658882E+0001, 8.99770816875836E+0001, 8.99713521090498E+0001, 8.99656225302295E+0001, 8.99598929510654E+0001, ...... 2.29198399677718E+0000, 2.14393684184771E+0000, 1.98488327611931E+0000, 1.81192713807401E+0000, 1.62062339292405E+0000, 1.40348933094521E+0000, 1.14593468971431E+0000, 8.10291437065700E-0001, 0.00000000000000E+0000 }; */ #define Tabl_acos 0x80000000 Чтоб не перепрошивалась каждый раз при перепрошивке, ее закоментил и в проге поставил дефайн Чёй-то 32? С какой радости? __allign (64) Кстати, если разкоментить таблицу, то все работает double arccos (double arg) { double argout; argout = Tabl_acos[(unsigned int)(fabs(arg*400))]; return (argout); } Изменено 20 августа, 2015 пользователем ZSN1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Obam 37 20 августа, 2015 Опубликовано 20 августа, 2015 · Жалоба __allign (64) http://www.keil.com/support/man/docs/armcc...ef_babdfecc.htm Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 20 августа, 2015 Опубликовано 20 августа, 2015 · Жалоба Кстати, если разкоментить таблицу, то все работает :08: И код уже поменялся, и преобразование типов вроде бы ни при чём. За вами не уследишь: советуешь что-то, а оно уже не актуально, всё поменялось Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ZSN1 0 20 августа, 2015 Опубликовано 20 августа, 2015 (изменено) · Жалоба :08: И код уже поменялся, и преобразование типов вроде бы ни при чём. За вами не уследишь: советуешь что-то, а оно уже не актуально, всё поменялось И это правильно - если чтото не так то нужно менять B) потом может по свободе докопаюсь ... Изменено 20 августа, 2015 пользователем ZSN1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться