Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: printf("\n float = %f \n", value.fVal); выкидывает из программы
Форум разработчиков электроники ELECTRONIX.ru > Cистемный уровень проектирования > Операционные системы > Linux
andybeg
пытаюсь конвертировать модбас данные во флоут

Цитата
union { float fVal; unsigned char bytes[4]; } value;
value.bytes[0] = data[4];
value.bytes[1] = data[3];
value.bytes[2] = data[6];
value.bytes[3] = data[5];
printf("\n float = %f \n", value.fVal);

и на принтфе просто без ругани выкидывает из программы
Savrik
Странно.. Код на первый взгляд без ошибок.. Попробуйте вместо data[х] присвоит какое-то значение, скажем, запишите туда единицы. И запустите
andybeg
попробовал ещё один вариант перевда во флоут
Цитата
float Float(const unsigned char* p)
{
float val;
memcpy(&val,p,sizeof(val));
return val;
}

arr[0] = data[4];
arr[1] = data[3];
arr[2] = data[6];
arr[3] = data[5];
fl = Float(arr);

printf("\n float = %f \n", fl);//(unsigned int)value.fVal);
результат тот е, только теперь уж понятно что вылетет именно при выводе числа
Savrik
мм.. даже не знаю.. На большом брате все работает, значит, трабл в железе.. компилируется без варнингов? Памяти досаточно?

А вообще что-либо printf() выводит?
andybeg
варнинг то я и не заметил
Цитата
incompatible implicit declaration of built-in function ‘memcpy’

правда ворнинг появляется только во втором варианте кнвертации, в первом его естественно нет

принтф печатает
Цитата
float = />
sergeeff
А вы уверены, что в вашем варианте printf вообще активирована поддержка float? Попробуйте, для проверки:

Код
float vv = 123.567;
printf("float = %f\n", vv);


Работает?
etoja
1) Формирование строки сделайте с помощью sprintf, а выдачу строки - с помощью printf.
2) В вашем компиляторе float может оказаться 16-битным и правильнее написать double.
3) Полезно почитать книгу Керниган Б.В. и Ричи Д.М. -Язык C
andybeg
Цитата
активирована поддержка float?
вероятно не активирована, не работает, по итогу привёл к инту и пользовал эти флоуты так, в конце концов пока что дробная часть не актуальна
Цитата
2) В вашем компиляторе float может оказаться 16-битным и правильнее написать double.
дабл постигла та же участь
Цитата
1) Формирование строки сделайте с помощью sprintf, а выдачу строки - с помощью printf.
3) Полезно почитать книгу Керниган Б.В. и Ричи Д.М. -Язык C
попробую
Xenia
При таком заполнении flоat-переменной
Код
union { float fVal; unsigned char bytes[4]; } value;
value.bytes[0] = data[4];
value.bytes[1] = data[3];
value.bytes[2] = data[6];
value.bytes[3] = data[5];

может оказаться, что вы записали в него "нечисло". Т.к. далеко не любая комбинация битов является валидным значением float.
А бедняга printf начинает конверировать инвалидное число в десятичное и сходит с ума smile.gif.
Мой совет: ... потренируйтесь на нулях smile.gif
andybeg
Цитата
может оказаться, что вы записали в него "нечисло". Т.к. далеко не любая комбинация битов является валидным значением float.
А бедняга printf начинает конверировать инвалидное число в десятичное и сходит с ума smile.gif.
Мой совет: ... потренируйтесь на нулях smile.gif
не сцать - записываю число, ибо после приведения к инту получаю правильное число без дробной части
forever failure
1. Каким образом первоначально формируются эти четыре байта ?
2. Порядок следования байт (little/big) endian, не ?
3. Тема целевой платформы, на которой происходит выполнение не раскрыта.
andybeg
Цитата
1. Каким образом первоначально формируются эти четыре байта ?
MODBUS и ещё раз повторюсь - разбираю я их верно

Цитата
3. Тема целевой платформы, на которой происходит выполнение не раскрыта.
а тема нет? никак не названа?
forever failure
Про тему пардон, в шары долблюсь.

Верно - это как ? Они из каких данных составляются, в коде покажите. Ну и опять же на АРМе порядок следования байт может быть любым. Он одинаков на обоих сторонах модбаса ?
andybeg
верно это так что с ttyS имею протокол модбас и входящую посылку <01><03><04><D1><C7><47><81><81><62> где болдом обозначены байты данных, они запихиваются в массив data c которым проводятся выше опсанные манипуляции и по итогу печатаем printf("\n float = %d \n", (unsigned int)fl); получая на выходе верное число без дробной части, а при чистом флоуте printf("\n float = %lf \n",fl); программа вылетает
sasamy
Цитата(andybeg @ Jul 21 2010, 18:44) *
value.bytes[0] = data[4];
value.bytes[1] = data[3];
value.bytes[2] = data[6];
value.bytes[3] = data[5];


Как-то приходилось работать с одним тепловычислителем, так там честно говорили что протокол modbus-подобный и float передавались с порядком байт little-endian друг за другом:

value.bytes[0] = data[3];
value.bytes[1] = data[4];
value.bytes[2] = data[5];
value.bytes[3] = data[6];
forever failure
Ну а на другом конце модбаса эти отмеченные болдом байты из чего берутся ?
И: верность числа в чём заключается ?

А так, в качестве опыта, - подставьте ваши болдом выделенные баты в любой хекс-эдитор, и посмотите, какому значению четырёхбайтной плавучки эти байты соответствуют.
andybeg
Цитата
value.bytes[0] = data[3];
value.bytes[1] = data[4];
value.bytes[2] = data[5];
value.bytes[3] = data[6];
с модбасом вапще часто творят что хотят, канонически быйты идут в том порядке в котором сделано у меня
forever failure
Пробую телепатировать: должно получится 66467.6, нет, не так ?

Если так, то ваш линукс и иполняемое приложение должно исползовать little endian порядок байт. Иначе пробуйте заполнять выше обозначенный унион в обратном порядке:
value.bytes[3] = data[4];
value.bytes[2] = data[3];
value.bytes[1] = data[6];
value.bytes[0] = data[5];
andybeg
Цитата
И: верность числа в чём заключается ?
предлагаю закрыть тему неверного фрмирования флоута, провёл эксперимент
Цитата
vv=123.456;
printf("\n int %d ",(unsigned int)(10*vv));
и на выходе получил 1234, думаю можно сделать вывод о том что проблемы именно с принтфом

Цитата
Пробую телепатировать: должно получится 66467.6, нет, не так ?
именно так
forever failure
Да именно так, похоже неверным оказывается printf
sasamy
Цитата(andybeg @ Jul 22 2010, 22:47) *
вероятно не активирована, не работает, по итогу привёл к инту и пользовал эти флоуты так, в конце концов пока что дробная часть не актуальна


Хе - сначала не заметил этот момент, там похоже какой-то лихой тулчейн используется, принципиально новый ;-)
sergeeff
Цитата(forever failure @ Jul 23 2010, 10:28) *
Да именно так, похоже неверным оказывается printf


Возьмите printf из любой библиотеки (например DietLib), переименуйте printf из этого модуля и подключите к своему проекту. Сразу все увидите. Удивительно сколько времени тратится на изучение "black box'a" в виде непонятно кем сделанной библиотеки.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.