#c #floating-point
#c #с плавающей запятой
Вопрос:
Я работаю с протоколом низкого уровня, который имеет высокую скорость передачи данных и поэтому использует 2 или 3 байта для представления a float
в зависимости от диапазона числа, чтобы сделать систему более эффективной.
Я пытаюсь проанализировать эти числа, но значения, которые я получаю, не имеют для меня смысла, все они равны нулю, и я не думаю, что устройство будет выводить ноль для рассматриваемых переменных.
Первые 5 байтов в моем буфере: FF-FF-FF-FF-FF
Первые два байта составляют a float t
. Следует отметить, что в документации говорится, что байты имеют малый порядковый номер.
Для анализа t
я делаю:
float t = 0;
memcpy(buffer, amp;t, 2);
Следующие 3 байта составляют float ax
, чтобы проанализировать, что я делаю:
float ax = 0;
memcpy(buffer 2, amp;ax, 3);
Это правильный способ справиться с этим? Сначала я устанавливаю оба t
и ax
равными нулю на случай, если вокруг будут случайные байты.
Обновить
Документация не очень хороша. Во-первых, они определяют a Float
как a 32-bit IEEE 754 floating-point number
.
Тогда есть эта цитата:
To increase efficiency many of the data packets are sent as 24-bit signed integer words
because 16-bits do not provide the range/precision required for many of the quantities,
whereas 32-bit precision makes the packet much longer than required.
Затем есть таблица, которая определяется t
как первые 2 байта буфера. В нем указано, что диапазон равен 0-59.999. В нем явно не указано, что это a Float
, я просто делаю это предположение.
Комментарии:
1. Если вы говорите о двоичной половинной точности 16, вы не можете просто скопировать байты в двоичную одинарную точность 32. Вы должны управлять преобразованием. Я никогда не слышал что-то о 3 байтах с плавающей запятой…
2. Я согласен с @LPs здесь. IEEE-754 обычно используется для представления числа с плавающей запятой. Вы не можете просто прочитать младшие
n
байты числа с плавающей запятой и предположить, что вы выбрали число сx
точностью. Для получения дополнительной информации см. thirum.al/2dk4tx93. Где-то в спецификации вашего низкоуровневого протокола должен быть определен точный формат этих чисел с плавающей запятой: сколько бит для экспоненты, сколько для мантиссы, как представлены знаки каждого?
4. Что содержат байты? Я никогда не слышал о 3-байтовых числах с плавающей запятой. Это не невозможно сделать, но почти наверняка это очень специфичный для приложения формат. Я использовал 46-битные (да, 46, не опечатка) числа с плавающей запятой, когда мне нужно было выжать максимум из формата хранения на диске, но затем кодирование и декодирование полностью выполнялись вручную путем сдвига битов, и я принимал очень осознанные решения о том, сколько битов мантиссы и экспонентыдля сохранения. Я подозреваю, что здесь происходит что-то подобное. Конечно, в документации должно быть больше, чем просто «3 байта с плавающей запятой».
5. Также часть о том, что оно равно от 0 до 59,999, означает, что это целое число из 2 байт, значения от 0 до 59999 в виде целого числа представляют от 00.000 до 59.999 для рассматриваемого поля (т.е. вы должны сами добавлять десятичный знак, это не число с плавающей запятой). Тот факт, что все это байты 0xFF, вероятно, означает, что ваше чтение не удалось и / или поле не заполнено. Я знаю, что для некоторых из этих полей MCOM GPS установлено значение 0xFF, когда для поля нет допустимых данных.
Ответ №1:
Возможно, у вас неправильные аргументы. Измените следующим образом:
memcpy (buffer, amp;t, 2);
Для
memcpy (amp;t, buffer, 2);
HTH
[редактировать: чтобы разъяснить всем тем людям, которые проголосовали за мой ответ, вопрос действительно содержит неправильные аргументы. Пытается прочитать буфер, но указывает его в качестве места назначения для memcpy]
Комментарии:
1. Не понижающий коэффициент, но копирование байтов из числа с плавающей запятой половинной точности в число с плавающей запятой одинарной точности не работает….
2. @LPs я понимаю, но OP не знает, почему он получает все нули. Пока он на самом деле не прочитает из своего буфера, он не будет знать, почему memcpy не работает для чисел с плавающей запятой.