преобразуйте int в float в шестнадцатеричный
-
21-09-2019 - |
Вопрос
Используя scanf, я хотел бы, чтобы моя программа вводила каждое введенное число распечатывала две строки:например
byte order: little-endian
> 2
2 0x00000002
2.00 0x40000000
> -2
-2 0xFFFFFFFE
-2.00 0xC0000000
Я могу заставить его распечатать 2 в шестнадцатеричном формате но мне также нужен float и, конечно, я не могу сканировать как один когда мне нужно также сканировать как int
Если я приведу значение с плавающей точкой при попытке printf, я получу ноль.Если я сканирую как значение с плавающей точкой я получаю правильный вывод.Я попытался преобразовать значение int в float, но оно по-прежнему равно нулю.
вот мой вывод на данный момент
Int - float - hex
byte order: little-endian
>2
2 0x000002
2.00 00000000
похоже, что я нормально конвертирую в float почему он не печатается как шестнадцатеричный?если я сканирую в виде числа с плавающей точкой, я получаю правильное шестнадцатеричное представление, как в первом примере.это должно быть что-то простое.мне действительно нужно сканировать в виде десятичной дроби имейте в виду я запускаю это в cygwin
вот что у меня есть на данный момент..
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int HexNumber;
float convert;
printf("Int - float - hex\n");
int a = 0x12345678;
unsigned char *c = (unsigned char*)(&a);
if (*c == 0x78)
{
printf("\nbyte order: little-endian\n");
}
else
{
printf("\nbyte order: big-endian\n");
}
printf("\n>");
scanf("%d", &HexNumber);
printf("\n%10d ",HexNumber);
printf("%#08x",HexNumber);
convert = (float)HexNumber; // converts but prints a zero
printf("\n%10.2f ", convert);
printf("%#08x", convert); // prints zeros
return 0;
}
Решение
попробуй это:
int i = 2;
float f = (float)i;
printf("%#08X", *( (int*) &f ));
[ПРАВИТЬ]
@Кори:
давайте разберем это изнутри наружу:
& f = address of f = say address 0x5ca1ab1e
(int*) &f = interpret the address 0x5ca1ab1e as integer pointer
* ((int*)&f) = get the integer at address 0x5ca1ab1e
следующее является более кратким, но трудно запомнить ассоциативность операторов языка C и приоритет операторов (я предпочитаю дополнительную ясность, которую обеспечивают некоторые добавленные скобки и пробелы):
printf("%#08X", *(int*)&f);
Другие советы
printf("%#08x", convert); // prints zeros
Эта строка не сработает, потому что вы говорите printf
что вы проходите в int
(используя %x
) но фактически вы передаете его в float
.
Каковы ваши намерения относительно этой строки?Чтобы показать двоичное представление числа с плавающей запятой в шестнадцатеричном формате?Если это так, возможно, вы захотите попробовать что-то вроде этого:
printf("%lx\n", *(unsigned long *)(&convert));
То, что делает эта строка, принимает адрес convert (&convert
) , который является указателем на значение с плавающей точкой и преобразует его в указатель на беззнаковый long (примечание:что тип, который вы вводите здесь, может отличаться в зависимости от размера float и long в вашей системе).Последний *
разыменовывает указатель на беззнаковый long в беззнаковый long, который передается printf
Учитывая int x, преобразование в float, затем распечатку байтов этого float в шестнадцатеричном формате можно было бы выполнить примерно так:
show_as_float(int x) {
float xx = x;
//Edit: note that this really prints the value as a double.
printf("%f\t", xx);
unsigned char *ptr = (unsigned char *)&xx;
for (i=0; i<sizeof(float); i++)
printf("%2.2x", ptr[i]);
}
Стандарты (C ++ и C99) предоставляют "специальное разрешение" для unsigned char
, так что безопасно использовать их для просмотра байтов любого объекта.C89 / 90 не гарантировал этого, но, тем не менее, он был достаточно портативным.