Идеально следующий код взял бы плавание в представлении IEEE 754 и преобразовал бы его в шестнадцатеричный
void convert() //gets the float input from user and turns it into hexadecimal
{
float f;
printf("Enter float: ");
scanf("%f", &f);
printf("hex is %x", f);
}
Я не слишком уверен, что идет не так, как надо. Это преобразовывает число в шестнадцатеричное число, но очень неправильное.
123.1443 gives 40000000
43.3 gives 60000000
8 gives 0
таким образом, это делает что-то, я просто не слишком уверен что.
Справка ценилась бы
Когда вы передаете float
в качестве аргумента вариативной функции (например, printf()
), он преобразуется в double
, который вдвое больше, чем float
(по крайней мере, на большинстве платформ).
Одним из способов обойти это было бы приведение float
к unsigned int
при передаче его в качестве аргумента в printf()
:
printf("hex is %x", *(unsigned int*)&f);
Это также более корректно, поскольку printf()
использует спецификаторы формата для определения размера каждого аргумента.
Технически это решение нарушает правило строгого алиасинга. Вы можете обойти это, скопировав байты float
в unsigned int
и затем передав его в printf()
:
unsigned int ui;
memcpy(&ui, &f, sizeof (ui));
printf("hex is %x", ui);
Оба эти решения основаны на предположении, что sizeof(int) == sizeof(float)
, что имеет место на многих 32-битных системах, но не обязательно так.
Если поддерживается, используйте% a для преобразования с плавающей запятой в стандартный шестнадцатеричный формат. Вот единственный документ , который мне удалось найти, в котором указан параметр% a.
В противном случае вы должны преобразовать биты значения с плавающей запятой в целочисленный тип известного размера. Если вы знаете, например, что и float, и int 32-битные, вы можете выполнить быстрое приведение:
printf( "%08X" , *(unsigned int*)&aFloat );
Если вы хотите меньше зависеть от размера, вы можете использовать объединение:
union {
float f;
//char c[16]; // make this large enough for any floating point value
char c[sizeof(float)]; // Edit: changed to this
} u;
u.f = aFloat;
for ( i = 0 ; i < sizeof(float) ; ++i ) printf( "%02X" , u.c[i] & 0x00FF );
Порядок цикла будет зависеть от порядка байтов архитектуры. Это пример с прямым порядком байтов.
В любом случае формат с плавающей запятой может быть непереносимым для других архитектур. Параметр% a предназначен для использования.
Как насчет этого:?
int main(void){
float f = 28834.38282;
char *x = (char *)&f;
printf("%f = ", f);
for(i=0; i<sizeof(float); i++){
printf("%02X ", *x++ & 0x0000FF);
}
printf("\n");
}