Сейчас на форуме: hgdagon, asfa, bartolomeo (+4 невидимых)

 eXeL@B —› Программирование —› Научите правильно переводить Float в Hex
Посл.ответ Сообщение

Ранг: 33.6 (посетитель)
Активность: 0.040
Статус: Участник

Создано: 01 января 2007 06:09
· Личное сообщение · #1

Где-то прочитал что надо последовательно умножать на 16 и каждая целая часть будет цифрой hex'a но что-то не совпадает.
Например hex редактор переводит 0.05 как 0x3D4CCCCD.
Подскажите как это делать.



Ранг: 56.3 (постоянный)
Активность: 0.030
Статус: Участник

Создано: 01 января 2007 06:16
· Личное сообщение · #2

basicproduction.nm.ru/articles/bpdblvb.htm
babbage.cs.qc.edu/IEEE-754/References.xhtml
babbage.cs.qc.edu/IEEE-754/Decimal.html




Ранг: 353.0 (мудрец)
Активность: 0.370
Статус: Участник
resreveR

Создано: 01 января 2007 06:36
· Личное сообщение · #3

hunger.ru/articles/num

-----
Тут не могла быть ваша реклама




Ранг: 33.6 (посетитель)
Активность: 0.040
Статус: Участник

Создано: 02 января 2007 14:56
· Личное сообщение · #4

Так что сначала в бинари переводить а потом ужо в hex? Может где лежит готовая функция под C++?




Ранг: 124.7 (ветеран)
Активность: 0.070
Статус: Участник

Создано: 02 января 2007 18:36
· Личное сообщение · #5

sliderZ
ну я подобную тему около недели назад поднимал уже
смотри на команды сопроцессора



Ранг: 60.4 (постоянный)
Активность: 0.030
Статус: Участник

Создано: 02 января 2007 20:03
· Личное сообщение · #6

Нужен просто перевод десятичной дроби? Или разобраться, как числа с плавающей точкой в памяти представляются?

ИМХО. Второе намного сложнее первого

ЗЫ. Кстати твой пример как раз ко второму вопросу и относится.



Ранг: 56.3 (постоянный)
Активность: 0.030
Статус: Участник

Создано: 02 января 2007 22:20
· Личное сообщение · #7

sliderZ пишет:
Так что сначала в бинари переводить а потом ужо в hex? Может где лежит готовая функция под C++?


Зачем переводить? В статье я перевёл только, чтобы было более наглядно. Составные части можно получить простыми действиями, типа:


HexFloat = 0x3D4CCCCD;
If (HexFloat & 0x80000000)
sign = True;
Else
sign = False;
Exp = ((HexFloat & 0x7F800000) >> 23) - 127;
Mantissa = HexFloat & 0xFFFFFF;


Что-то вроде этого. Хотя, если тебя устройство неинтересует, то можно положи это число в регистр сопроцессора, а потом считай его представление в память, команды сейчас не вспомню, но если тебе именно это нужно, то могу глянуть.

Кстати в OLLYDasm есть функции:
Printfloat10
Printfloat8
Printfloat4

Их тоже следует посмотреть.



Ранг: 2.5 (гость)
Активность: 0.010
Статус: Участник

Создано: 02 января 2007 22:37
· Личное сообщение · #8

Хочу добавить, все, что находится после дробной точки обрабатывается по-другому, вроде, зеркально наоборот обычному преобразованию (здесь я могу ошибаться).
Очень давно такую прогу писал, если исходники найду - поделюсь, только там Делфи.



Ранг: 2.5 (гость)
Активность: 0.010
Статус: Участник

Создано: 02 января 2007 22:52
· Личное сообщение · #9

Вот самая общая формула для перевода в любую систему счисления:
A(p) = a_(n-1)*p^(n-1) + a_(n-2)*p^(n-2)+...+a_1*p^1 +a_0*p^0
p - основание, а - цифра, n - номер старшего разряда
Т.е. мы складываем произведения количественных значений цифр на степени основания, показатели которых равны номерам разрядов, нумерация разрядов идет от нуля.

В прошлом посте я очипся, зеркально отображается дробная часть отрицательного числа, нам это не надо. С дробными числами лучше работать каким-нибудь циклом управляющим значением степени, а для дробной части ничего не измениться, обрабатываться все будет также, но с отрицательной степенью.

На эту тему очень много литературы написано, думаю, стоит поискать.



Ранг: 33.6 (посетитель)
Активность: 0.040
Статус: Участник

Создано: 03 января 2007 03:04
· Личное сообщение · #10

W[4Fh]LF
W[4Fh]LF пишет:
HexFloat = 0x3D4CCCCD;
If (HexFloat & 0x80000000)
sign = True;
Else
sign = False;
Exp = ((HexFloat & 0x7F800000) >> 23) - 127;
Mantissa = HexFloat & 0xFFFFFF;


Так это Hex->Float , а нужно Float->Hex.. У меня без перевода в бинари массив пока не получается.



Ранг: 27.7 (посетитель), 2thx
Активность: 0.01=0.01
Статус: Участник

Создано: 03 января 2007 04:44
· Личное сообщение · #11

sliderZтогда объясняй точнее, чего хочешь.
"перевести float в HEX" можно понять как угодно, потому что эта фраза типа "перевести круглое в красное".

например можно так переводить
0.05(значение переменной типа float) -> "0.0ССССС..." (HEX строка)

или так
"0.05"(строка десятичного числа)-> sscanf в переменную типа float -> прочесть переменную как unsigned int -> "3D4CCCCD" (HEX строка)

я так понял, что скорее всего, нужно что-то похожее на то, что делает sscanf?

а то может быть у тебя три переменных
int a,b,c; // a-целые=0, b-десятые=0, с-сотые=5
нужно представить эквивалент числа abc в
float d;



Ранг: 495.3 (мудрец)
Активность: 0.30
Статус: Участник

Создано: 03 января 2007 06:31
· Личное сообщение · #12

sliderZ пишет:
У меня без перевода в бинари массив пока не получается.

Ну, Nitrogen сказал же, - посмотри справочник команд FPU:
http://exelab.ru/f/action=vthread&forum=6&topic=7230

-----
Всем привет, я вернулся




Ранг: 310.8 (мудрец), 29thx
Активность: 0.430
Статус: Участник

Создано: 03 января 2007 06:32
· Личное сообщение · #13

sliderZ пишет:
Где-то прочитал что надо последовательно умножать на 16 и каждая целая часть будет цифрой hex'a

Это правильно для перевода мантиссы. В каждой приличной книжке по программированию в конце описывается формат плавающего числа. Боюсь соврать, но что-то вроде такого. Любое положительное плавающее число представляется в виде m*2**n, где m - мантисса - число в диапазоне 1-1/2, а n - показатель. Далее мантисса переводится именно так, как ты написал. Т.к. первый бит мантиссы равен 1, то он не пишется. Показатель записывается в виде 127+n, т.е. занимает ровно 8 бит. Мантисса 23-бита + бит знака. Где он точно пишется не помню. Для двойной точности - 6 байт мантисса и 2 -порядок
И еще - в самом сопроцессоре 80 бит и там что-то похожее на двойную точность.



Ранг: 33.6 (посетитель)
Активность: 0.040
Статус: Участник

Создано: 03 января 2007 07:28 · Поправил: sliderZ
· Личное сообщение · #14

ant_manant_man пишет:
sliderZтогда объясняй точнее, чего хочешь.
"перевести float в HEX" можно понять как угодно, потому что эта фраза типа "перевести круглое в красное".


Есть число "0.05", нужна функция переводящая его в "0x3D4CCCCD". Что тут не понятного?
Нужно что-то типа

W[4Fh]LF пишет:
HexFloat = 0x3D4CCCCD;
If (HexFloat & 0x80000000)
sign = True;
Else
sign = False;
Exp = ((HexFloat & 0x7F800000) >> 23) - 127;
Mantissa = HexFloat & 0xFFFFFF;

только наоборот.

Bitfry

Bitfry пишет:
Ну, Nitrogen сказал же, - посмотри справочник команд FPU:


Так что без __asm вставки никак?

tundra37


tundra37 пишет:
В каждой приличной книжке по программированию в конце описывается формат плавающего числа


Я уже все это прочитал и понял просто не хватает опыта написать на c++ небольшую функцию, которая автоматом переводит float в integer.



Ранг: 56.3 (постоянный)
Активность: 0.030
Статус: Участник

Создано: 03 января 2007 07:34 · Поправил: W[4Fh]LF
· Личное сообщение · #15

sliderZ пишет:
Так это Hex->Float , а нужно Float->Hex..


В первом сообщении дал тебе ссылку:
[url=http://basicproduction.nm.ru/articles/bpdblvb.htm
]http://basicproduction.nm.ru/articles/bpdblvb.htm
[/url]

Bitfry пишет:
Ну, Nitrogen сказал же, - посмотри справочник команд FPU:


FPU тут вряд ли поможет, ибо те команды, которые в той теме давали они сохраняют или BCD(команда fbstp), т.е. фактически только целую часть, или округлённое до целого значение из ST(0), команда fistp, такой команды, чтобы взять и выгрузить в память значение с плавающей точкой нет.



Ранг: 56.3 (постоянный)
Активность: 0.030
Статус: Участник

Создано: 03 января 2007 07:45
· Личное сообщение · #16

sliderZ пишет:
Я уже все это прочитал и понял просто не хватает опыта написать на c++ небольшую функцию, которая автоматом переводит float в integer.


Чё ж ты раньше молчал? Это тебе смекалки нехватает

#include <stdio.h>
#include <windows.h>

int main( void )
{
float x = 0.05;
unsigned int y;
RtlCopyMemory(&y, &x, sizeof( float ));
printf("Float Value = %f Hex Value = 0x%x", x, y);
return 0;
}


>>

E:TempСИ>prog.exe
Float Value = 0.050000
Hex Value = 0x3d4ccccd
E:TempСИ>



Ранг: 33.6 (посетитель)
Активность: 0.040
Статус: Участник

Создано: 03 января 2007 08:31 · Поправил: sliderZ
· Личное сообщение · #17

W[4Fh]LF

printf("Float Value = %f Hex Value = 0x%x", x, y);


Только через printf? А арифметически никак?




Ранг: 240.5 (наставник)
Активность: 0.190
Статус: Участник
Author of ACKiller

Создано: 03 января 2007 08:44
· Личное сообщение · #18

sliderZ
Через sprintf
А если серьезно, тебе дали достаточно информации, почитай и осмысли.



Ранг: 56.3 (постоянный)
Активность: 0.030
Статус: Участник

Создано: 03 января 2007 09:22
· Личное сообщение · #19

sliderZ пишет:
Только через printf? А арифметически никак?


Всмысле арифметически вывести на экран чтоли? Это как вообще?



Ранг: 27.7 (посетитель), 2thx
Активность: 0.01=0.01
Статус: Участник

Создано: 03 января 2007 10:02
· Личное сообщение · #20

если число уже в переменной типа float лежит, то ничего и делать не надо.

float x=0.05;

*(DWORD*)&x == 0x3D4CCCCD



Ранг: 33.6 (посетитель)
Активность: 0.040
Статус: Участник

Создано: 03 января 2007 11:39 · Поправил: sliderZ
· Личное сообщение · #21

ant_manant_man пишет:
*(DWORD*)&x


Афигеть. Гениально. Спасибо.



Ранг: 1.4 (гость)
Активность: 0=0
Статус: Участник

Создано: 05 января 2007 13:53
· Личное сообщение · #22

Вот на асме, результат в eax.

__ftol2_sse proc near
var_24 = dword ptr -24h
var_14 = qword ptr -14h
var_C = qword ptr -0Ch

push ebp
mov ebp, esp
sub esp, 8
and esp, 0FFFFFFF8h
fstp [esp+0Ch+var_C]
cvttsd2si eax, [esp+0Ch+var_C]
leave
retn
__ftol2_sse endp



Ранг: 88.3 (постоянный), 3thx
Активность: 0.040
Статус: Участник

Создано: 05 января 2007 14:08
· Личное сообщение · #23

cvttsd2si - Convert Scalar Double-Precision Floating-Point Value to Signed Doubleword Integer with Truncation
- только с семьи Pentium 4, на ранних процах работать не будет...

Напридумывали бл.... Кто видел новую инструкцию, говорят есть уже в пятых пентах:
ssbrfidwoeietqbdtbgifag #X -
SetSexthBitRegisterFlagIfDoubleWordOfEaxIsEqualToQuadroBufferDueToBill GatesIsFuckenAmericanGuy...


 eXeL@B —› Программирование —› Научите правильно переводить Float в Hex
:: Ваш ответ
Жирный  Курсив  Подчеркнутый  Перечеркнутый  {mpf5}  Код  Вставить ссылку 
:s1: :s2: :s3: :s4: :s5: :s6: :s7: :s8: :s9: :s10: :s11: :s12: :s13: :s14: :s15: :s16:


Максимальный размер аттача: 500KB.
Ваш логин: german1505 » Выход » ЛС
   Для печати Для печати