Структура IEEE754 - PullRequest
       4

Структура IEEE754

1 голос
/ 16 февраля 2012

мой вопрос касается одинарных номеров разрешений IEEE 754.Предположим, у меня есть структура:

typedef struct __ieee754
{ 
   int sign;
   int exponent;
   int mantissa;
} IEEE754,*pIEEE754;

Могу ли я преобразовать это в одно число percision (1-8-23 float)?Я использую C.

Ответы [ 3 ]

4 голосов
/ 16 февраля 2012

Предположим, что ваша реализация использует числа одинарной точности IEEE 754 для float, что-то вроде этого должно работать

struct __ieee754 f;
/* set f to something valid */
float x = f.sign * f.mantissa * pow(2, f.exponent);
3 голосов
/ 16 февраля 2012

Один из двух предыдущих ответов должен быть неверным - вопрос задан недостаточно. Нам нужно знать, содержит ли структура двоичное представление компонентов с плавающей запятой IEEE или содержит числовое определение.

Исходя из того, что они являются целыми числами, первое более вероятно: -4.2 будет представлено как {1,0x81,0x066666} или 0xC0866666. В этом случае ответ @ ouah будет правильным, а @ pmg даст 2.85e44.

С другой стороны, чтобы код @ pmg был верным, структура для -4.2 должна быть сохранена как {-1,-21,0x433333}. А затем применение алгоритма @ ouah дает 0xF5C33333, что равно -4.9489e32, если интерпретировать его как число с плавающей запятой IEEE.

Если мы предполагаем, что вы используете первое представление, то существует непереносимая уловка процессора, которая может упростить ваш код. Переопределите вашу структуру как объединение следующим образом.

union flt  {  
    struct ieee754 {
       unsigned int mantissa:23;
       unsigned int exponent:8;
       unsigned int sign:1;
    } raw;
    float f;
 }

(Вам может понадобиться изменить порядок аргументов в зависимости от вашего процессора - и убедиться, что упаковка правильная - это непереносимая часть)

Теперь ваш код может записывать непосредственно в память в виде битов и считывать их обратно с плавающей точкой:

  union flt num;
  num.raw.sign = 1;
  num.raw.exponent = 129;
  num.raw.mantissa = 0x66666;
  printf("%f", num.f);  //prints 4.2
3 голосов
/ 16 февраля 2012

Предполагается, что 32-битная unsigned int и IEEE-754 одинарная точность float тип:

union bla {
    unsigned int a;
    float b;
};

union bla num = {
        (((unsigned int) f.sign & 1) << 31)
      | (((unsigned int) f.exponent & 0xFF) << 23)
      | ( (unsigned int) f.mantissa & 0x7FFFFF); 
};

printf("%f\n", num.b)
...