首页 文章

C中浮动到基础2科学记数法(IEEE 32位)的算法或代码?

提问于
浏览
2

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

    所以我不打算为你完成所有的工作,因为这听起来像是家庭作业 . 但我会让你开始,你可以填补空白 . 因此,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位,你想把它转换成一个int,这样做每个位乘以2 ^ i(23位是0,24位是1等)然后你会想要减去int的偏移量 . 然后使用先前的大纲方法输出指数的二进制表示,我会考虑不输出,直到你达到1.希望这有帮助 .

  • 0

    你可以作弊,只需使用frexp .

  • 0

    最简洁的方法之一是使用bitmasking . 也许更好的方法是使用位域 . 您可以定义一个结构来表示浮点格式:

    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 .

  • 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);
    }
    

相关问题