Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Необычный перевод числа с плавающей точкой, Авторский формат данных, помогите 
V
    Опции темы
NullModemUser
Дата 15.8.2014, 13:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 3
Регистрация: 15.8.2014

Репутация: нет
Всего: нет



Здравствуйте!

Работая с протоколом одной железяки, наткнулся на поле, что хранит температуру. Хранит оно в формате числа с плавающей точкой.
Но не как в IEEE-754.

Автор, в документе протокола приводит следующее описание с примером (привожу как в документе, БЕЗ опечаток, 1 к 1):

Цитата

Sf3 - 4 байта

1 байт - порядок. Значение порядка кратно 2, если младший бит равен 1, то число отрицательное, если значение порядка 0, то число равно нулю.

3 байт - старший байт мантиссы. Если старший бит равен 0, то результат выключен.

2,1 байты. Соответственно средний и мл. байты мантиссы.

Примеры чисел:

1    - 80h 00 00 80h
2    - 82h 00 00 80h
4    - 84h 00 00 80h
-4   - 85h 00 00 80h
0,5 - 7Eh 00 00 80h
Выкл - 86h 00 00 7Fh


Помогите, пожалуйста, разобраться. Как перевести, скажем температуру 27,33 в данный формат представления числа. И наоборот.

Заранее спасибо! 
PM MAIL   Вверх
AVA12
Дата 15.8.2014, 14:32 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 135
Регистрация: 4.5.2008

Репутация: 1
Всего: 4



Да, в принципе, все понятно. Формат, в целом, похож на число одинарной точности (single), только лишний бит мантиссы откусил часть экспоненты. Плюс смещение экспоненты другое. Ну и поля переставлены.

Будем работать с числом в новом формате, как с 32-битным целым, порядок байтов - LE (aka "интеловский"). В таком случае между новым форматом и single будут следующие соответствия:
Код
new     single  comment
31      -       1 - корректное число, 0 - "выкл"
30..8   22..0   мантисса
7..1    30..23  экспонента (без знака, со смещением);
                для перевода new -> single нужно прибавить 63, если наоборот, то вычесть
0       31      знак числа

PM ICQ Jabber   Вверх
AVA12
Дата 15.8.2014, 15:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 135
Регистрация: 4.5.2008

Репутация: 1
Всего: 4



На всякий случай о представлении нуля: если все биты и мантиссы, и экспоненты - нулевые, то при переводе в другой формат соответствующие биты должны остаться нулевыми. Как быть с денормализованными числами и нечислами - непонятно, но, раз уж железка хранит значения температуры, то такие случаи вряд ли встретятся smile
PM ICQ Jabber   Вверх
NullModemUser
Дата 15.8.2014, 16:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 3
Регистрация: 15.8.2014

Репутация: нет
Всего: нет



AVA12, огромное спасибо! Но можете еще помочь...
Смотрите.

Мы имеем число-константу 1.000258.
Железяка нам его выдает в виде: ED 03 71 82h

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

Распишите пожалуйста, как Вы его переводите в single... 
PM MAIL   Вверх
AVA12
Дата 15.8.2014, 17:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 135
Регистрация: 4.5.2008

Репутация: 1
Всего: 4



А ты уверен, что это именно 1.000258? Если верить описанию формата, ED 03 71 82 должно представлять -18358002335612930. А с другим порядком байт - чуть больше 3.7

Это сообщение отредактировал(а) AVA12 - 15.8.2014, 17:45
PM ICQ Jabber   Вверх
NullModemUser
Дата 20.8.2014, 09:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 3
Регистрация: 15.8.2014

Репутация: нет
Всего: нет



AVA12, спасибо за за помощь! Таки да, ошибся я с числом, криво разобрал наснифанный пакет.

В итоге привожу Дельфячный код (переложить на С++ или т.п. элементарно, написано крайне просто):

Код

function SpecSingleToSingle(InValue: DWord): Single;
CONST
  OFFBITMASK = $ffffff7f;
  SIGNBITMASK = $01000000;
  EXPONENTMASK = $fe000000;
  EXPONENTCORRECTIONCONST = ($3f000000 shr 1);
  MANTISSBYTE1MASK = $0000007f;
  MANTISSBYTE2MASK = $0000ff00;
  MANTISSBYTE3MASK = $00ff0000;

var PreResult: DWord;
     sign, exponent, mantiss: DWord;
begin
  InValue := InValue AND OFFBITMASK;

  sign := ((InValue AND SIGNBITMASK) shl 7);

  exponent := (((InValue AND EXPONENTMASK) shr 2) + EXPONENTCORRECTIONCONST);

  mantiss := (((InValue AND MANTISSBYTE1MASK) shl 16) OR
               ((InValue AND MANTISSBYTE3MASK) shr 16) OR
               (InValue AND MANTISSBYTE2MASK));

  PreResult := 0 OR sign OR exponent OR mantiss;

  Result := Single(PSingle(PreResult));
end;

PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Алгоритмы"

maxim1000

Форум "Алгоритмы" предназначен для обсуждения вопросов, связанных только с алгоритмами и структурами данных, без привязки к конкретному языку программирования и/или программному продукту.


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, maxim1000.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Алгоритмы | Следующая тема »


 




[ Время генерации скрипта: 0.0438 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.