|
Не считает функция log(). |
|
|
|
Oct 21 2014, 16:50
|
Участник

Группа: Участник
Сообщений: 42
Регистрация: 8-10-11
Пользователь №: 67 615

|
Споткнулся на ровном месте. Надо подсчитывать натуральный логарифм. Иcпользую функцию log(), logf(), но как-то странно работает. send_base массив 16 битных слов. В таком виде не работает. Код volatile float x=((adc_ext_result[i]/5*20000.0)/(65535.0-adc_ext_result[i]/5)); send_base[adc_ext_index[i]]=logf(x); x=21521.0; log(x)= 65535. А так работает: Код volatile float x=((adc_ext_result[i]/5*20000.0)/(65535.0-adc_ext_result[i]/5)); float r=21521.0; send_base[adc_ext_index[i]]=logf(r); logf®=9; arm-none-eabi-gcc (GNU Tools for ARM Embedded Processors) 4.8.4 20140725 (release) [ARM/embedded-4_8-branch revision 213147] на работе пробовал компилить другим тулчайном резльтат тот же. Не могу понять где копать.
|
|
|
|
2 страниц
1 2 >
|
 |
Ответов
(1 - 22)
|
Oct 21 2014, 18:16
|
Участник

Группа: Участник
Сообщений: 42
Регистрация: 8-10-11
Пользователь №: 67 615

|
был выровнен на 4 байта. Поставил 8. Ничего не изменилось. Попробовал стек увеличить до 2к. Тоже никаких изменений. Пробовал другие функции , тоже не работают. Пробовал log10, sin. подключаю: #include <math.h>
|
|
|
|
|
Oct 21 2014, 18:47
|
Участник

Группа: Участник
Сообщений: 42
Регистрация: 8-10-11
Пользователь №: 67 615

|
-lm поставил последним ключом. Поставил 8. Не считает . Удивительно, что сама по себе библиотека работает.
Ага. Что-то стало прояснятся. У меня эта функция находилась в прерывании, я вытащил ее в майн. И нашел глюк. Значения для функции меняются произвольным образом, т.е. похоже где-то косяк, который в функцию кидает похоже отрицательные числа. Спасибо огромное за помощь. А то уже руки опустились.
|
|
|
|
|
Oct 22 2014, 04:11
|
Участник

Группа: Участник
Сообщений: 42
Регистрация: 8-10-11
Пользователь №: 67 615

|
Спасибо про суффикс попробую запомнить, float использую да, для скорости. Все таки полное непонимание. Значит вчера я усомнился, что в функцию попадают корректные данные. Сегодня стал проверять и оказалось, что не понимаю в чем эти данные некорректные. Я могу вывести на дисплей данные, которые находятся в массиве send_base. Массив uint16_t. Выводить на дисплея я умею только uint16_t. Если код такой: Код float r=((adc_ext_result[i]*(20000.0f/5.0f))/(65535.0f-adc_ext_result[i]/5.0f)); send_base[adc_index[0]]=r; send_base[adc_ext_index[i]]=logf(r); то, значение r плавает около 12570 (это результат измерения ацп) значение logf® всегда 65535. Меняю код на следущий: Код float r=((adc_ext_result[i]*(20000.0f/5.0f))/(65535.0f-adc_ext_result[i]/5.0f)); uint16_t x=(uint16_t)r; send_base[adc_index[0]]=x; send_base[adc_ext_index[i]]=logf(x); значение x такое же, а вот значение функции logf(x) становится правильным =9. Не понимаю, что происходит. Так тоже работает: send_base[adc_ext_index[i]]=logf((uint16_t)r); Наверно самое главное забыл сказать. У меня контроллер stm32f051. Т.е. cortex-m0. Может какие-то специальные ключи нужны для компилятора? Я ставлю ключи: -mcpu=cortex-m0 -mthumb
|
|
|
|
|
Oct 22 2014, 04:26
|
Местный
  
Группа: Участник
Сообщений: 280
Регистрация: 2-11-08
Пользователь №: 41 333

|
Цитата(scifi @ Oct 21 2014, 23:05)  Кстати, выражение "adc_ext_result[i]/5*20000.0" выглядит совсем плохо. Я бы написал "adc_ext_result[i]*(20000.0f/5)". А я попробовал бы записать "adc_ext_result[i]*4000.0f"
Сообщение отредактировал sidy - Oct 22 2014, 04:26
|
|
|
|
|
Oct 22 2014, 05:20
|
Участник

Группа: Участник
Сообщений: 42
Регистрация: 8-10-11
Пользователь №: 67 615

|
Я могу посмотреть только целые, поэтому и вижу 9. Умножаю результат на 1000, вижу для х=12866, logf(x)*1000=9462, это вот прямо сейчас на диcплее. Т.е. если в функцию кладу целое, то считается нормально, если флоат, как требует объявление функции то результат - переполнение. Я понимаю, что какие-то траблы с преобразованием целое-флоат. Но в каком месте и почему не понимаю. варнингов нет. толчайн брал здесь - https://launchpad.net/gcc-arm-embeddedgnu math: Function: float logf (float x) сейчас посмотрю исходники тулчайна если найду, но я думаю, что траблы где-то в другом месте. Тулчайн оказывается стоит Sourcery. А по ссылке, которую приводил, стоит дома. Но с обоими тулчайнами результат одинаков. в math.h extern float logf _PARAMS((float));
|
|
|
|
|
Oct 22 2014, 05:30
|
Участник

Группа: Участник
Сообщений: 42
Регистрация: 8-10-11
Пользователь №: 67 615

|
Криво.
|
|
|
|
|
Oct 22 2014, 09:42
|
Участник

Группа: Участник
Сообщений: 42
Регистрация: 8-10-11
Пользователь №: 67 615

|
Глюк мой. Плохое понимание преобразования типов. Ожидал, что преобразование из плавающего в целое беззнаковое будет осуществляться как в знаковое, оказывается знак просто откидывается. Т.е. значение 21521, на самом деле было -21521.0. Поэтому и было переполнение. Всем спасибо за внимание и помощь.
|
|
|
|
|
Oct 22 2014, 10:48
|
Участник

Группа: Участник
Сообщений: 42
Регистрация: 8-10-11
Пользователь №: 67 615

|
Да. Вы правы. Проверил, преобразовывает именно так. Тогда вообще ничего не понимаю. Может быть кроме преобразования отрицательного в целое безнаковое еще и переполнение было?
Да. если происходит переполнение, то результат не предсказуем.
|
|
|
|
|
Oct 22 2014, 11:15
|
Участник

Группа: Участник
Сообщений: 42
Регистрация: 8-10-11
Пользователь №: 67 615

|
Читал, не единожды. Видимо голова небольшого объема. Я собственно оветил, чтобы отметить, что с компилятором как всегда все ок.
|
|
|
|
|
Oct 22 2014, 15:36
|
Гуру
     
Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454

|
Цитата Каждый раз веселюсь, когда вижу, как свойства языка Си снова открывают эмпирическим путём тут это уже на уровне руки помнят. То есть всю жизнь было так и я всегда это применял, но когда увидел запись что нет, задумался... вдруг это не закон а просто всегда везло  . Такой фигни много бывает, стирается из памяти источник знаний, остаются только факты и опыт применений. Весело, возможно, но что не стыдно сто пудово  ... У флоат если мне не изменяет память есть спец символ +- бесконечность. Может на него так log реагирует? exp(65535) - это прям дофига-дофигища, и число уж больно интересное 16 единичек... проверил, виндовый калькулятор на e^65535 честно заявляет переполнение, хотя и на 65534 тоже), где то в районе 22000 предел наступает. При этом я уверен он считает в даблах, так что для флота переполнение еще раньше. Скорее всего полученный ответ - это какой-то флаг...
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|