|
|
  |
Ошибка конверсии (unsigned int) double ? |
|
|
|
Aug 20 2015, 06:35
|
Группа: Новичок
Сообщений: 9
Регистрация: 20-08-15
Пользователь №: 88 062

|
Вычисляю 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. Глюк компилятора?
|
|
|
|
|
Aug 20 2015, 10:49
|
Группа: Новичок
Сообщений: 9
Регистрация: 20-08-15
Пользователь №: 88 062

|
Сделал втупую Код 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 Возможно в других диапазонах тоже самое Цитата(scifi @ Aug 20 2015, 08:21)  Только это всё равно ничего не изменит. У меня есть версия. Возможно, стек не выравнен по границе 8 байт, и из-за этого не работает умножение double*double. А как стек выровнять? Добавить __align(32)?
Сообщение отредактировал ZSN1 - Aug 20 2015, 10:51
|
|
|
|
|
Aug 20 2015, 11:03
|
Группа: Новичок
Сообщений: 9
Регистрация: 20-08-15
Пользователь №: 88 062

|
Таблица зашита во внешнюю 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 Чтоб не перепрошивалась каждый раз при перепрошивке, ее закоментил и в проге поставил дефайн Цитата(Obam @ Aug 20 2015, 10:57)  Чёй-то 32? С какой радости? __allign (64) Кстати, если разкоментить таблицу, то все работает Код double arccos (double arg) { double argout; argout = Tabl_acos[(unsigned int)(fabs(arg*400))]; return (argout); }
Сообщение отредактировал ZSN1 - Aug 20 2015, 11:04
|
|
|
|
|
Aug 20 2015, 11:37
|
Группа: Новичок
Сообщений: 9
Регистрация: 20-08-15
Пользователь №: 88 062

|
Цитата(scifi @ Aug 20 2015, 11:34)   И код уже поменялся, и преобразование типов вроде бы ни при чём. За вами не уследишь: советуешь что-то, а оно уже не актуально, всё поменялось  И это правильно - если чтото не так то нужно менять  потом может по свободе докопаюсь ...
Сообщение отредактировал ZSN1 - Aug 20 2015, 11:38
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|