3

我将浮点数作为输入,然后以 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

4 回答 4

2

所以我不会为你做所有的工作,因为这听起来像是家庭作业。但我会让你开始,你可以填补空白。因此,在 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。本质上,您将检查符号位打印 - 或 + 取决于它,然后 1. 然后跳到尾数并打印以下内容。然后你会回到 23-30 位,你想将它转换为一个 int,为此将每个位乘以 2^i(23 位是 0,24 位是 1,等等)然后你会想从int中减去偏移量。然后使用前面的大纲方法输出指数的二进制表示,我会考虑在你达到 1 之前不输出。希望这会有所帮助。

于 2010-10-03T18:45:01.073 回答
0

您可以作弊,只需使用frexp

于 2010-10-03T18:13:18.937 回答
0
#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);
}
于 2012-05-10T20:35:56.010 回答
0

最干净的方法之一是使用位掩码。也许更好的方法是使用位域。您可以定义一个结构来表示浮点格式:

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

然后得到你的浮点数,并将其转换为这个结构:

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

这会重新解释数据位而不更改它们。然后,您可以轻松地以数字形式访问这些部件。只需记住为 exp 添加偏移量并为尾数添加前导 1。

于 2010-10-03T19:12:26.383 回答