реклама на сайте
подробности

 
 
> Не считает функция log().
-Игорь-
сообщение Oct 21 2014, 16:50
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 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]
на работе пробовал компилить другим тулчайном резльтат тот же. Не могу понять где копать.
Go to the top of the page
 
+Quote Post
2 страниц V   1 2 >  
Start new topic
Ответов (1 - 22)
AHTOXA
сообщение Oct 21 2014, 17:57
Сообщение #2


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



А у вас стек выровнен на 8 байт?


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
-Игорь-
сообщение Oct 21 2014, 18:16
Сообщение #3


Участник
*

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



был выровнен на 4 байта. Поставил 8. Ничего не изменилось. Попробовал стек увеличить до 2к. Тоже никаких изменений.
Пробовал другие функции , тоже не работают. Пробовал log10, sin.
подключаю:
#include <math.h>
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Oct 21 2014, 18:32
Сообщение #4


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Оставьте 8, так надо.
-lm линкеру не забыли?
Ещё смутно помню, что -lm должна быть последней из библиотек в командной строке линкера. Но тут могу что-то путать.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
-Игорь-
сообщение Oct 21 2014, 18:47
Сообщение #5


Участник
*

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



-lm поставил последним ключом. Поставил 8. Не считает .
Удивительно, что сама по себе библиотека работает.

Ага. Что-то стало прояснятся. У меня эта функция находилась в прерывании, я вытащил ее в майн. И нашел глюк. Значения для функции меняются произвольным образом, т.е. похоже где-то косяк, который в функцию кидает похоже отрицательные числа. Спасибо огромное за помощь. А то уже руки опустились.
Go to the top of the page
 
+Quote Post
scifi
сообщение Oct 21 2014, 19:05
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Кстати, выражение "adc_ext_result[i]/5*20000.0" выглядит совсем плохо. Я бы написал "adc_ext_result[i]*(20000.0f/5)".
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Oct 21 2014, 19:07
Сообщение #7


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Да не за чтоsm.gif
Кстати, если вы по какой-то причине хотите считать исключительно с float (ну, быстродействие, размер кода, или что-то ещё), то константы пишите с суффиксом f: 65535.0f. Без этого у вас в правой части выражения всё считается в double, и только потом конвертируется в float.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
-Игорь-
сообщение Oct 22 2014, 04:11
Сообщение #8


Участник
*

Группа: Участник
Сообщений: 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
Go to the top of the page
 
+Quote Post
sidy
сообщение Oct 22 2014, 04:26
Сообщение #9


Местный
***

Группа: Участник
Сообщений: 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
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Oct 22 2014, 04:45
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



вообще то
log(12570) != 9;
он равен
9.4390683015842931064461706132924

вы уверен что косяк в момент вычисления log, а не в момент перевода флота в целое? Просто если флот на входе воспринимается как инт, то есть 2 ичное представление, то получается огромное число и косяк...

я бы для верности сделал

(int)log((float)x);

кстати вы уверены что у вас в библиотеки флотовый логарифм? и нет ли варнинга о неявном его объявлении? потому что если так, то иногда среды все неявные функции считают объявленными с интовым входом и что не пихай думают что это инт.

Go to the top of the page
 
+Quote Post
-Игорь-
сообщение Oct 22 2014, 05:20
Сообщение #11


Участник
*

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



Я могу посмотреть только целые, поэтому и вижу 9. Умножаю результат на 1000, вижу для х=12866, logf(x)*1000=9462, это вот прямо сейчас на диcплее.
Т.е. если в функцию кладу целое, то считается нормально, если флоат, как требует объявление функции то результат - переполнение.
Я понимаю, что какие-то траблы с преобразованием целое-флоат. Но в каком месте и почему не понимаю.

варнингов нет. толчайн брал здесь - https://launchpad.net/gcc-arm-embedded
gnu math: Function: float logf (float x)
сейчас посмотрю исходники тулчайна если найду, но я думаю, что траблы где-то в другом месте.

Тулчайн оказывается стоит Sourcery. А по ссылке, которую приводил, стоит дома. Но с обоими тулчайнами результат одинаков.

в math.h
extern float logf _PARAMS((float));
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Oct 22 2014, 05:24
Сообщение #12


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



а что такое _PARAMS ?

попробуйте так, ну чтобы наверняка?
answer = (int)log( ((float)x) );

если криво будет, то остается только одно, что в библиотеке стоит какая-то левая функция на точке входа logf, которая считает что-то не то
Go to the top of the page
 
+Quote Post
-Игорь-
сообщение Oct 22 2014, 05:30
Сообщение #13


Участник
*

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



Криво.
Go to the top of the page
 
+Quote Post
-Игорь-
сообщение Oct 22 2014, 09:42
Сообщение #14


Участник
*

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



Глюк мой. Плохое понимание преобразования типов.
Ожидал, что преобразование из плавающего в целое беззнаковое будет осуществляться как в знаковое, оказывается знак просто откидывается. Т.е. значение 21521, на самом деле было -21521.0. Поэтому и было переполнение.
Всем спасибо за внимание и помощь.
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Oct 22 2014, 10:21
Сообщение #15


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



странно, обычно знаковое преобразуется в знаковое

float a = -21521.0;
int b = (int)a == -21521;
причем дробная часть просто отбрасывается, потому округление положительных и отрицательных в разные стороны

неужели в gcc не так?
Go to the top of the page
 
+Quote Post
-Игорь-
сообщение Oct 22 2014, 10:48
Сообщение #16


Участник
*

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



Да. Вы правы. Проверил, преобразовывает именно так.
Тогда вообще ничего не понимаю. Может быть кроме преобразования отрицательного в целое безнаковое еще и переполнение было?

Да. если происходит переполнение, то результат не предсказуем.
Go to the top of the page
 
+Quote Post
scifi
сообщение Oct 22 2014, 11:00
Сообщение #17


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(-Игорь- @ Oct 22 2014, 14:48) *
Проверил, преобразовывает именно так.

Каждый раз веселюсь, когда вижу, как свойства языка Си снова открывают эмпирическим путём :-)
А книжку почитать не судьба? В том же K&R всё хорошо написано. Иначе будете по этим граблям блуждать и дальше.
Go to the top of the page
 
+Quote Post
-Игорь-
сообщение Oct 22 2014, 11:15
Сообщение #18


Участник
*

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



Читал, не единожды. Видимо голова небольшого объема.
Я собственно оветил, чтобы отметить, что с компилятором как всегда все ок.
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Oct 22 2014, 15:36
Сообщение #19


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



Цитата
Каждый раз веселюсь, когда вижу, как свойства языка Си снова открывают эмпирическим путём


тут это уже на уровне руки помнят. То есть всю жизнь было так и я всегда это применял, но когда увидел запись что нет, задумался... вдруг это не закон а просто всегда везлоsm.gif. Такой фигни много бывает, стирается из памяти источник знаний, остаются только факты и опыт применений. Весело, возможно, но что не стыдно сто пудовоsm.gif...

У флоат если мне не изменяет память есть спец символ +- бесконечность. Может на него так log реагирует? exp(65535) - это прям дофига-дофигища, и число уж больно интересное 16 единичек...

проверил, виндовый калькулятор на e^65535 честно заявляет переполнение, хотя и на 65534 тоже), где то в районе 22000 предел наступает. При этом я уверен он считает в даблах, так что для флота переполнение еще раньше. Скорее всего полученный ответ - это какой-то флаг...

Go to the top of the page
 
+Quote Post
scifi
сообщение Oct 22 2014, 16:06
Сообщение #20


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(Golikov A. @ Oct 22 2014, 19:36) *
Такой фигни много бывает, стирается из памяти источник знаний, остаются только факты и опыт применений. Весело, возможно, но что не стыдно сто пудовоsm.gif...

Расскажу по секрету: есть такие полезные штуки - "справочники" называются. Очень помогают. А в наш век тырнетов и гуглов они все на расстоянии вытянутой руки. Пользуйтесь, пока санкции тырнет не отрубили :-)
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Oct 22 2014, 17:33
Сообщение #21


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



вы все известные вам факты, от которых вы забыли источник, пробиваете по гуглу?
Go to the top of the page
 
+Quote Post
scifi
сообщение Oct 22 2014, 19:12
Сообщение #22


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(Golikov A. @ Oct 22 2014, 21:33) *
вы все известные вам факты, от которых вы забыли источник, пробиваете по гуглу?

Скажем так: перед обращением к помощи форума обязательно сверяюсь со справочниками. Кстати, что-то давно не обращался :-)
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Oct 22 2014, 20:05
Сообщение #23


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



не делаете ничего нового, наверное? wink.gif
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 19th July 2025 - 22:45
Рейтинг@Mail.ru


Страница сгенерированна за 0.0154 секунд с 7
ELECTRONIX ©2004-2016