Преобразуйте плавание ieee 754 для преобразовывания в шестнадцатеричную систему с c - printf

Идеально следующий код взял бы плавание в представлении 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

таким образом, это делает что-то, я просто не слишком уверен что.

Справка ценилась бы

17
задан James McNellis 31 May 2010 в 02:40
поделиться

3 ответа

Когда вы передаете 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-битных системах, но не обязательно так.

26
ответ дан 30 November 2019 в 10:53
поделиться

Если поддерживается, используйте% 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 предназначен для использования.

12
ответ дан 30 November 2019 в 10:53
поделиться

Как насчет этого:?

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");
}
1
ответ дан 30 November 2019 в 10:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: