Алгоритм или код для плавания в базу 2 научной нотации (IEEE 32 бит) в C ++? - PullRequest
2 голосов
/ 03 октября 2010

В качестве входных данных я принимаю float, а затем выводю его эквивалентное представление в научной записи Base 2.Это в IEEE 32 бита с: 31 знаковый бит, показатель 23-30 (со смещением 127), мантисса 0-22 (с неявным ведением 1).

Одно из условий, в которых я не совсем уверензначение этого слова: «Ваша мантисса должна иметь неявную начальную 1 с добавлением начальных значений».

Все, что я действительно узнал, это разбить поплавок на его десятичные и дробные части и отдельно получить их двоичные представления.*

Так как я не уверен, как это сделать ... я не могу написать код.Буду признателен за любые советы или информацию о каком-либо алгоритме для этого или самом коде.Спасибо.

Пример:

Input: -40.1
Output: -1.01000000110011001100110 E101

Input: 13.5
Output: 1.10110000000000000000000 E11

РЕДАКТИРОВАТЬ: 127 смещение означает избыток 127 нотации правильно?В моей книге только 128, но я все равно не знаю разницы ...

Ответы [ 4 ]

2 голосов
/ 03 октября 2010

Так что я не собираюсь делать всю работу за вас, потому что это звучит как домашнее задание.Но я вас начну, и вы можете заполнить пробелы.Таким образом, в c ++ есть удобный тип данных, который называется объединением, с его помощью вы можете иметь несколько типов данных, занимающих одно и то же место.Это очень полезно, если, скажем, вы хотите увидеть битовое представление числа с плавающей запятой.Следующий код выведет двоичное представление числа с плавающей запятой:

#include <iostream>
using namespace std;
union b{
   float flo;
   int integ;
};
int main(){

  b thing;
  thing.flo=-40.1;
  for(int i=31;i>=0;i--){
    if((thing.integ & (1 << i)))
      cout << 1;
    else
      cout << 0;
  }
  cout << endl;
}

Все, что вам остается сделать - это извлечь мантиссу и экспоненту.Вы можете запустить процедуру один раз, чтобы сгенерировать мантиссу, и снова, чтобы сгенерировать показатель степени.Я дам краткое объяснение того, как сделать и то, и другое, на что следует обратить внимание.

При создании мантиссы помните, что IEEE использует скрытый 1 с зарезервированным кодом для нуля, поэтому всегда будетдополнительный, которого нет в битовом представлении.По сути, вы проверите бит печати знака - или + в зависимости от этого, затем 1. затем перейдите к мантиссе и напечатайте то, что следует.Затем вы вернетесь к 23-30 битам, вы хотите преобразовать его в целое число, чтобы сделать это, умножив каждый бит на 2 ^ i (23 бита - 0, 24 бита - 1 и т. Д.), А затемхочу вычесть смещение из int.Затем, используя ранее набросанный метод вывода двоичного представления показателя степени, я бы не стал выводить, пока вы не нажмете 1. Надеюсь, это поможет.

0 голосов
/ 11 мая 2012
#include <iostream>

//float:1:8:23, bias 127
typedef union {
    float f;
    unsigned int ui;
    unsigned char c[4];
} Fl_u;
/*    
bool isLittleEndian(){
    Fl_u x;
    x.f = -0.0;
    return x.c[3] == 0x80;
}
*/
void fbinprint(float f){
    Fl_u x;
    unsigned wk=0;
    x.f = f;
/*  if(isLittleEndian())
        for(int i=3;i>=0;--i)
            wk = (wk << 8) + x.c[i];
    else
*/      wk = x.ui;
    if(wk & 0x80000000)
        std::cout << '-';
    unsigned bit = wk & 0x07FFFFF;
    std::cout << "1.";
    for(int i = 0; i< 23 ; ++i){
        bit <<=1;
        std::cout << (bit & 0x0800000 ? '1' : '0');
    }
    std::cout << " E";
    int exp = (wk >> 23) & 0x0FF;
    exp -= 127;//bias 127
    if(exp < 0){
        std::cout << '-';
        exp = -exp;
    }
    int i = 0;
    while((exp & 0x080) == 0 && i < 8){//skip zero of top
        exp <<= 1;
        ++i;
    }
    if(i == 8)
        std::cout << '0';
    for(;i< 8 ; ++i){
        std::cout << (exp & 0x080 ? '1' : '0');
        exp <<=1;
    }
    std::cout << std::endl;
}

int main(){
    float f = -40.1;
    std::cout << "Input: " << f << std::endl;
    std::cout << "Output: ";
    fbinprint(f);
    std::cout << std::endl;
    f = 13.5;
    std::cout << "Input: " << f << std::endl;
    std::cout << "Output: ";
    fbinprint(f);
//  fbinprint(0.0625);
}
0 голосов
/ 03 октября 2010

Один из самых чистых способов сделать это с помощью маскировки.Возможно, лучший способ с битовыми полями.Вы можете определить структуру для представления формата с плавающей запятой:

struct float_layout {
  int mantisa : 23
  int exp : 8
  int sign : 1
};

Затем получите ваш float и приведите его к этой структуре:

float b = input;
float_layout layout = *static_cast<float_layout *>(&b)

Это переосмысливает биты данных без измененияих.Тогда вы можете легко получить доступ к частям в виде чисел.Просто не забудьте добавить смещение для опыта и добавить ведущую 1 для мантиссы.

0 голосов
/ 03 октября 2010

Вы можете обмануть, и просто использовать frexp .

...