Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Форматы файлов и данных > Формат представления данных


Автор: UniBomb 18.3.2009, 13:20
Сорри если не в тот раздел, но более подходящего я не нашёл)))

Итак, ситуация - уже три года что я работаю на текущем месте я занимаюсь сопровождением одной программы, которую писал мой предшественник. Программа написана на avr'овском ассемблере и по объёму занимает 3333 строки, причём написана впопыхах и местами очень коряво. За эти три года я почти полностью изучил её методами тыка и наблюдения за поведением, но осталось одно большое белое пятно - я так и не понял в каком формате представляются данные. А тут как раз задача изменить некоторые из них. Вот в определении формата я и прошу помощи  smile 

Каждое число занимает 4 байта и являеться вещественным. По коду частенько встречаються инструкции вида:

Код

    ldi  r26,0x00
            ldi  r25,0x19
            ldi  r24,0x20
            ldi  r23,0x20
            sub  r23,r16
            sbc  r24,r17
            sbc  r25,r18
            sbc  r26,r19
            brmi GEL6
            ldi  r30,low(malo) 
            ldi  r31,high(malo)
            ijmp
            
GEL6:  


что в переводе на более понятный ЯП выглядит так:

Код

if((x - c) < 0)
 malo();


где с - не представляет интереса, а x - это и есть искомое число (х = ([0x00][0x19][0x20][0x20])

лазая по программе я нашёл несколько явных указаний этих числе как в примере выше и точно знаю их значения:

х = ([0x00][0x19][0x20][0x20]) = 0,9
х = ([0x01][0x33][0x00][0x00]) = 1,2
х = ([0x16][0xBA][0x2E][0x8B]) = 22,72727272

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

Сначала я думал что числа представлены в формате с плавающей запятой, но тогда былобы вот так:

х = ([0x00][0x19][0x20][0x20]) = 2,30741168252039E-39
х = ([0x01][0x33][0x00][0x00]) = 3,28771076245609E-38
х = ([0x16][0xBA][0x2E][0x8B]) = 3,00792934331708E-25

Потом я заметил, что старший байт равен целой части числа и после этого предположил, что это формат с фиксированной запятой, но несмог декодировать числа:


00.192020(16) = 0,1646624(10) //не то

00.192020(16) = 00000000,000110010010000000100000(2) = 0 + 1*2^-4 + 1*2^-5 + 0*2^-8 + etc = ~0,078(10) //не то

00.192020(16) = 0000.0000,0001.1001.0010.0000.0010.0000(2) = 0 + 1*10^-1+9*10^-2+etc = 0,19101(10) //не то

В общем помогите пожалуйста  smile 

зы: переписать всё это дело на С желание возникало многократно, но всё руки недоходили...

Автор: dumb 18.3.2009, 20:47
1,2 * 2^24 = 20132659,2 = 0x1333333
22,72727272 * 2^24 = 381300363,51434752 = 0x16BA2E8B

во-первых, видимо значения(кроме последнего) несколько округленные.
а во-вторых 0,9 - это по всей видимости просто ошибка, ибо 0x192020 / 2^24 = 0,0981464385986328125

Автор: nickless 18.3.2009, 21:03
Это называется ИМХО Q16.24 http://en.wikipedia.org/wiki/Q_(number_format)

Автор: dumb 18.3.2009, 21:58
почти. полагаю таки 7.24 smile

Автор: UniBomb 18.3.2009, 22:26
Цитата(dumb @  18.3.2009,  20:47 Найти цитируемый пост)
а во-вторых 0,9 - это по всей видимости просто ошибка, ибо 0x192020 / 2^24 = 0,0981464385986328125

Посыпаю голову пеплом - да, 0,09  smile 


Цитата(dumb @  18.3.2009,  20:47 Найти цитируемый пост)
во-первых, видимо значения(кроме последнего) несколько округленные.

Видимо да, т.к. первые два числа я мог отследить только по показаниям, выводимым на дисплей, а на нём показывалось до двух знаков после запятой. Причём значения ниже 0,09 и выше 1,2 непоказывались (это такие ограничения прибора) и 1,2 показывалось чотко как 1,20.


Цитата(nickless @  18.3.2009,  21:03 Найти цитируемый пост)
Q16.24

Цитата(dumb @  18.3.2009,  21:58 Найти цитируемый пост)
7.24

Спасибо вам обоим за ответ  smile 

Автор: nickless 18.3.2009, 23:10
Цитата(dumb @  18.3.2009,  20:58 Найти цитируемый пост)
полагаю таки 7.24

А, сорри, считать разучился smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)