Вопрос

У меня есть этот фрагмент кода, который выдает неправильные результаты.

#include <stdio.h>
#include <string.h>

int main() 
{
  unsigned char bytes[4];
  float flt=0;

  bytes[0]=0xde;
  bytes[1]=0xad;
  bytes[2]=0xbe;
  bytes[3]=0xef;

  memcpy( &flt, bytes, 4);

  printf("bytes 0x%x float %e\n", flt, flt);
  return 0;
}

результат, который я получаю, это

байты 0xc0000000 с плавающей точкой -2.000001e+00

Я ожидаю получить

байты 0xdeadbeef с плавающей запятой -6.2598534e+18

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

байты 0xefbeadde с плавающей запятой -1.1802469e+29

чего я не понимаю, так это приведение из float в unsigned int, приводящее к 0xc0000000 (значение float в том же операторе printf равно -2.0000, которое я бы приписал оптимизации компилятора)

раньше это работало на другом компьютере.Это может быть изменение архитектуры.

Это было полезно?

Решение

Это не проблема memcpy.

  1. float всегда преобразуется в double когда прошел над ... из printf, так что вы просто не можете получить 4 байта на большинстве архитектур Intel.
  2. когда вы экспонируете 0xdeadbeef в этом коде вы предполагаете, что ваша архитектура имеет БОЛЬШОЙ порядковый номер.Существует множество архитектур с малым расширением, например Intel x86.

Другие советы

Вы понимаете, что значения с плавающей запятой увеличиваются в два раза при передаче в функцию переменных параметров, такую как printf()?Поэтому, когда ты говоришь:

printf("bytes 0x%x float %e\n", flt, flt);

вы пытаетесь рассматривать то, что на самом деле является двумя 8-байтовыми значениями, как два 4-байтовых значения, дающие (я полагаю) неопределенное поведение.

"%x" в printf ожидает значение unsigned int.Вы даете ему значение с плавающей точкой, которое автоматически преобразуется, а это не то, что вы хотите.Вы хотите сделать что-то вроде:

printf("bytes 0x%x float %e\n", *((unsigned int *)&flt), flt);

О, и, как кто-то еще указал, если вы используете x86, вы не увидите 0xdeadbeef, скорее 0xefbeadde.

Посмотрим, станет ли это хоть немного лучше:

printf("bytes 0x%x float %e\n", *(int *)&flt, flt);

Чтобы увидеть повышение параметра, измените объявление с float на double.На моей машине, которая печатает:

bytes 0xefbeadde float -1.860545e+230

Значение 0xefbeadde имеет порядковый номер для deadbeaf.Последние 4 байта double не определены, поэтому число, отображаемое после float, будет отличаться.

Вы упомянули, что это работало на другом компьютере, что это был за компьютер?Должно быть, это был маленький конец, где sizeof(float) == sizeof(double) :)

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top