IEEE-754 отображение float
- Войдите на сайт для отправки комментариев
Пт, 20/12/2019 - 23:03
Добрый день,
Подскажите по конвертации, имеем 4 байта 0x436b580e, по правилам IEEE-754 в DEC float должно быть 235.344. Как заставить float заставить отобразить правильно это число? Пробую разные варианты получается 1131108352.00
Побуду Дедом Морозом.
void setup() { uint32_t nInteger; float* ptrFloat; Serial.begin(9600); nInteger = 0x436b580e; ptrFloat = (float*) &nInteger; Serial.println(*ptrFloat, 3); } void loop() {}Супер! спасибо большое. Не хватало этой
float* ptrFloatзвездочки у меня. А что она значит? когда используется?Коль такая новогодняя шара, спрошу еще, если у меня два uint16_t, как лучше их объединить? чтобы конвертировать во float
Супер! спасибо большое. Не хватало этой
float* ptrFloatзвездочки у меня. А что она значит? когда используется?https://prog-cpp.ru/c-pointers/
Зависит от того что и как в этих uint16_t хранится. Например если сделать так:
uint16_t s1 = 0x1234; uint16_t s2 = 0x5678; uint32_t l = s1 << 16 | s2;То в l получим 0x12345678
если у меня два uint16_t, как лучше их объединить? чтобы конвертировать во float
Чую запах модбаса, который несёт данные с электросчётчика. Что за модель?
typedef union { uint16_t u16[2]; uint32_t u32; float flt; } convertor_t; void setup() { Serial.begin(9600); convertor_t convertor; uint16_t swap; convertor.u16[0x00] = 0x436b; convertor.u16[0x01] = 0x580e; Serial.print("UINT_32 (1): 0x"); Serial.println(convertor.u32, HEX); swap = convertor.u16[0x00]; convertor.u16[0x00] = convertor.u16[0x01]; convertor.u16[0x01] = swap; Serial.print("UINT_32 (2): 0x"); Serial.println(convertor.u32, HEX); Serial.print("FLOAT : "); Serial.println(convertor.flt, 3); } void loop() {}если у меня два uint16_t, как лучше их объединить? чтобы конвертировать во float
Чую запах модбаса, который несёт данные с электросчётчика. Что за модель?
typedef union { uint16_t u16[2]; uint32_t u32; float flt; } convertor_t; void setup() { Serial.begin(9600); convertor_t convertor; uint16_t swap; convertor.u16[0x00] = 0x436b; convertor.u16[0x01] = 0x580e; Serial.print("UINT_32 (1): 0x"); Serial.println(convertor.u32, HEX); swap = convertor.u16[0x00]; convertor.u16[0x00] = convertor.u16[0x01]; convertor.u16[0x01] = swap; Serial.print("UINT_32 (2): 0x"); Serial.println(convertor.u32, HEX); Serial.print("FLOAT : "); Serial.println(convertor.flt, 3); } void loop() {}Да, в точку)) DDS578R в пути еще, пока по мануалу разбираюсь. Прикрутить к домашней сети модбас хочу
Супер! спасибо большое. Не хватало этой
float* ptrFloatзвездочки у меня. А что она значит? когда используется?https://prog-cpp.ru/c-pointers/
Зависит от того что и как в этих uint16_t хранится. Например если сделать так:
uint16_t s1 = 0x1234; uint16_t s2 = 0x5678; uint32_t l = s1 << 16 | s2;То в l получим 0x12345678
По указателю прочитал, спасибо, доходчиво написано. А то по звездочки не гуглилось.
А по преобразованию также хотел сделать, но нужно проверять.
А то, что sadman41 написал, нужно разбираться. для меня там много не очевидных вещей.
Да, в точку)) DDS578R в пути еще, пока по мануалу разбираюсь. Прикрутить к домашней сети модбас хочу
Ну, удачи. У меня был такой опыт со счётчиком.
Своп регистров понадобится, если все регистры пачкой принять, а потом во флоаты конвертить.
если у меня два uint16_t, как лучше их объединить? чтобы конвертировать во float
Через union. И конвертировать ничего не надо.
Да, в точку)) DDS578R в пути еще, пока по мануалу разбираюсь. Прикрутить к домашней сети модбас хочу
Ну, удачи. У меня был такой опыт со счётчиком.
Своп регистров понадобится, если все регистры пачкой принять, а потом во флоаты конвертить.
Опыт положительный или оказалось игрушкой?
Принимать, конечно, пачкой планирую. А свап в смысле просто старший и младший местами менять или Swap endianness
если у меня два uint16_t, как лучше их объединить? чтобы конвертировать во float
Чую запах модбаса, который несёт данные с электросчётчика. Что за модель?
typedef union { uint16_t u16[2]; uint32_t u32; float flt; } convertor_t; void setup() { Serial.begin(9600); convertor_t convertor; uint16_t swap; convertor.u16[0x00] = 0x436b; convertor.u16[0x01] = 0x580e; Serial.print("UINT_32 (1): 0x"); Serial.println(convertor.u32, HEX); swap = convertor.u16[0x00]; convertor.u16[0x00] = convertor.u16[0x01]; convertor.u16[0x01] = swap; Serial.print("UINT_32 (2): 0x"); Serial.println(convertor.u32, HEX); Serial.print("FLOAT : "); Serial.println(convertor.flt, 3); } void loop() {}sadman41, перечитал кучу заметок касаемо union, но так до меня и не доходит, как элемет convertor.u32 получается последовательность двух предыдущих элементов и как convertor.flt преобразуется именно из элемента convertor.u32.
Может не там читаю, тогда буду благодарен за ссылку на источник.
Может не там читаю, тогда буду благодарен за ссылку на источник.
Одна и та же область памяти (4 байта) рассматривается или как uint32_t или как float или как массив uint16_t[2]. То, как компилятор её интерпретирует - зависит от указания имени члена объединения.
Пишем convertor.flt - компилятор рассматривает 4 байта, как float, convertor.u32 - как uint32_t и т.п. То же самое приведение типов указателя, как и в первом примере, только скрытое.
Картинку нашёл только такую:
Спасибо за информацию.
А uint32_t получается можно вообще убрать?
А typedef нужен только для подмены имени типа union?
Можно и убрать, если не нужен для контроля. Использовать typedef - это моя личная заморочка(привычка).
можно и так, без typedef
using TVar = union { uint8_t Bytes[4]; uint16_t Words[2]; uint32_t DWord; float Float; }; TVar Variable; . . . Variable.Float = PI; Serial << "PI = " << Variable.DWord << eoln;