没有bug的程序员 2022-12-18 18:07 采纳率: 100%
浏览 32
已结题

十进制浮点数 转754标准(32位)十六进制出现的问题

十进制浮点数 转I3e-754标准(32位)十六进制:
在网上看了这样一段代码
原文链接:https://blog.csdn.net/m0_37957160/article/details/111569131#:~:text=1.%E5%B0%86%EF%BC%8832%E4%BD%8D%EF%BC%8916%E8%BF%9B%E5%88%B6IEEE-754%E6%A0%87%E5%87%86%E6%B5%AE%E7%82%B9%E6%95%B0%E5%B0%B1%E6%98%AF%E7%94%A8%E5%8D%81%E5%85%AD%E8%BF%9B%E5%88%B6%E8%A1%A8%E7%A4%BA%E6%B5%AE%E7%82%B9%EF%BC%8C%E7%A7%B0%E4%B8%BA%E5%8D%95%E7%B2%BE%E5%BA%A6%E6%B5%AE%E7%82%B9%E6%95%B0%E3%80%82,float%E7%B1%BB%E5%9E%8B%E5%9C%A8%E5%86%85%E5%AD%98%E4%B8%AD%E5%8D%A04%E4%B8%AA%E5%AD%97%E8%8A%82%EF%BC%8832%E4%BD%8D%EF%BC%89%EF%BC%8C%E6%9C%80%E9%AB%98%E4%BD%8D%E7%94%A8%E4%BA%8E%E8%A1%A8%E7%A4%BA%E7%AC%A6%E5%8F%B7%3B%E5%9C%A8%E5%89%A9%E4%B8%8B%E7%9A%8431%E4%BD%8D%E4%B8%AD%EF%BC%8C%E4%BB%8E%E5%8F%B3%E5%90%91%E5%B7%A6%E4%BA%868%E4%BD%8D%E7%94%A8%E4%BA%8E%E8%A1%A8%E7%A4%BA%E6%8C%87%E6%95%B0%EF%BC%8C%E5%85%B6%E4%BD%99%E7%94%A8%E4%BA%8E%E8%A1%A8%E7%A4%BA%E5%B0%BE%E6%95%B0%E3%80%82%20%EF%BC%88%E4%B8%80%E4%B8%AA%E5%AD%97%E8%8A%82%E6%98%AF8%E4%BD%8D%EF%BC%89

验算的链接:http://www.speedfly.cn/tools/hexconvert/
@Upupup6 出自于他的一篇文章,讲了十进制数转十六进制I3e754格式的数,但我发现,这个地方输入的数值超过255的时候,得到的结果就有问题了。
搞了好几天了,一直都是这样的。
第一次在csdn上提问题,这样子说应该没什么问题吧,原文链接和作者我都有@了,如果还有哪些不妥还希望小伙伴说一下,我重新改一次。

#include<iostream>
#include<vector>
#include"math.h"
#include<iomanip>
#include <fstream>
 
using namespace std;
 
vector<bool> zhengshu;//存整数部分的二进制
vector<bool> xiaoshu;//存小数部分的二进制
 
vector<bool> get_zhengshu_2b(float a)
{
    vector<bool> x;
    x.clear();
    //八位二进制a xxxx xxxx与1000 0000与,得到每位的二进制数
    for (int i = 0; i < 8; i++)
    {
        if ((((int)a)&(0x80 >> i)))
        {
            x.push_back(1);
        }
        else
        {
            x.push_back(0);
        }
    }
    return x;
}
 
void get_2b(float a)
{
    //获取整数部分的二进制码
    float fabs_a = fabs(a);//取绝对值
    zhengshu.clear();
    xiaoshu.clear();
    zhengshu = get_zhengshu_2b(fabs_a);
 
    //获取小数部分的二进制码
    float n = 2;   //小数位的阶数取倒数
    float b = (fabs_a - floor(fabs_a));
 
    //每次除以2判断该位是0还是1
    while (!b == 0)
    {
        if ((1.0 / n) < b)
        {
            xiaoshu.push_back(1);
            //若为1则b减去该位所对应的十进制小数大小 ,继续判断低一位,直到b=0
            b = b - (1.0 / n);
        }
        else if ((1.0 / n) > b)
        {
            xiaoshu.push_back(0);
        }
        else if ((1.0 / n) == b)
        {
            xiaoshu.push_back(1);
            break;
        }
        n = n * 2;
    }
}
int get_jiema()  //返回阶码
{
    for (int i = 0; i < 8; i++)
    {
        if (zhengshu[i] == 1)//判断从左边起第一个为1的位置
            return 7 - i;        // 返回阶码大小
    }
}
vector<bool> get_yima()//得到移码
{
    int e = get_jiema();
    e = e + 127;  //阶码偏移得到移码
    return get_zhengshu_2b(e);//返回获得的移码的二进制形式
}
vector<bool> get_weima()//获得尾码
{
    vector <bool> m;
    //小数的二进制前插入规格化的码得到尾码
    xiaoshu.insert(xiaoshu.begin(), zhengshu.begin() + (8 - get_jiema()), zhengshu.end());
    m = xiaoshu;
    return m;
}
vector<bool> to_IEEE754(float x)
{
    vector<bool> IEEE;
    IEEE.clear();
    get_2b(x);   //得到x的二进制码
    /*
    //输出原数的二进制形式
    cout << "绝对值的二进制数为:" << endl;
    for (int i = 0; i < zhengshu.size(); i++)
    {
        cout << zhengshu[i];
    }
    cout << ".";
    for (int i = 0; i < xiaoshu.size(); i++)
    {
        cout << xiaoshu[i];
    }
    cout << endl;
    //输出移码
    cout << "移码为:" << endl;
    vector<bool> E = get_yima();
    for (int i = 0; i < 8; i++)
    {
        cout << E[i];
    }
    cout << endl;
    */
    //组合成短浮点数代码:
    vector<bool> yima;
    yima.clear();
    yima = get_yima();
    vector<bool> weima;
    weima.clear();
    weima = get_weima();
 
    if (x > 0)//判断并添加符号位
    {
        IEEE.insert(IEEE.end(), 1, 0);
    }
    else
    {
        IEEE.insert(IEEE.end(), 1, 1);
    }
    IEEE.insert(IEEE.end(), yima.begin(), yima.end());//添加移码
    IEEE.insert(IEEE.end(), weima.begin(), weima.end());//添加尾码
    IEEE.insert(IEEE.end(), 32 - 9 - weima.size(), 0);//尾部补零 共32位
    return IEEE;
}
void get_hex(vector<bool> E)//得到十六进制显示
{
    ofstream out;
    out.open("D:\\Desktop\\输出.txt", ios::app);
 
    vector<bool>::iterator ite = E.begin();//迭代器
    int sum = 0;
    int n = 8;
    while (n--)//八组循环
    {
        for (int i = 0; i < 4; i++)//求每4位的十六进制表示
        {
            sum = sum + (*ite)*pow(2, 3 - i);//8 4 2 1
            ite++;
        }
 
        cout << setiosflags(ios::uppercase) << hex << sum;//16进制大写字母输出
 
        out << setiosflags(ios::uppercase) << hex << sum;// 写入文件
        sum = 0;
    }
    out << endl;
    out.close();
    cout << endl;
}
 
 
 
int main()
{
 
    ifstream in;
    in.open("D:\\P1.txt");
    //求十进制的短浮点数代码//
 
    if (!in.good())
    {
        cout << "文件打开失败" << endl;
        system("pause");
        return 0;
    }
    while (!in.eof())
    {
        float x;
        vector<bool> IEEE;
        in >> x;
        cout << x <<"转换为:" ;
        IEEE = to_IEEE754(x);
        get_hex(IEEE);
        IEEE.clear();
        cout  << endl;
        //system("pause");
    }
    in.close();
    cout << "转换完成" << endl;
    system("pause");
 
    return 0;
 
}

  • 写回答

1条回答 默认 最新

  • 赵4老师 2022-12-19 12:15
    关注

    仅供参考:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    int main() {
        float f;
        double d;
        char bs[65];
        char b[65];
        char s[80];
        unsigned char *p;
        char e[12];
        char *t;
        int ex;
        int flag;
    
        flag=0;
        while (1) {
            printf("Input a float point number or 0xXXXXXXXX or 0xXXXXXXXXXXXXXXXX:");fflush(stdout);
            rewind(stdin);
            fgets(s,80,stdin);
            if ('\n'==s[0]) return 1;
            if (1==sscanf(s,"0x%16I64X",(__int64 *)&d) && strlen(s)>11) {flag=2;break;}
            if (1==sscanf(s,"0x%8X"    ,(  int   *)&f))                 {flag=1;break;}
            if (1==sscanf(s,"%f"       ,           &f)
             && 1==sscanf(s,"%lf"      ,           &d))                 {flag=3;break;}
        }
        if (flag&1) {
            printf("f=%g\n",f);
            p=(unsigned char *)&f;
            printf("hex=%02X %02X %02X %02X\n",p[3],p[2],p[1],p[0]);
            ltoa(*(long *)&f,b,2);
            sprintf(bs,"%032s",b);
            printf("bin=%s\n",bs);
            printf("bin=%.1s %.8s   %s\n",bs,bs+1,bs+9);
            strncpy(e,bs+1,8);e[8]=0;
            ex=strtol(e,&t,2);
            printf("    %c %-4d-127 1.%s\n",(bs[0]=='0')?'+':'-',ex,bs+9);
            ex-=127;
            printf("    %c %-8d 1.%s\n",(bs[0]=='0')?'+':'-',ex,bs+9);
        }
        if (flag&2) {
            printf("\nd=%lg\n",d);
            p=(unsigned char *)&d;
            printf("hex=%02X %02X %02X %02X %02X %02X %02X %02X\n",p[7],p[6],p[5],p[4],p[3],p[2],p[1],p[0]);
            _i64toa(*(__int64 *)&d,b,2);
            sprintf(bs,"%064s",b);
            printf("bin=%s\n",bs);
            printf("bin=%.1s %.11s   %s\n",bs,bs+1,bs+12);
            strncpy(e,bs+1,11);e[11]=0;
            ex=strtol(e,&t,2);
            printf("    %c %-6d-1023 1.%s\n",(bs[0]=='0')?'+':'-',ex,bs+12);
            ex-=1023;
            printf("    %c %-11d 1.%s\n",(bs[0]=='0')?'+':'-',ex,bs+12);
        }
    
        return 0;
    }
    //Input a float point number or 0xXXXXXXXX or 0xXXXXXXXXXXXXXXXX:0x3FC0000000000000
    //
    //d=0.125
    //hex=3F C0 00 00 00 00 00 00
    //bin=0011111111000000000000000000000000000000000000000000000000000000
    //bin=0 01111111100   0000000000000000000000000000000000000000000000000000
    //    + 1020  -1023 1.0000000000000000000000000000000000000000000000000000
    //    + -3          1.0000000000000000000000000000000000000000000000000000
    //
    //Input a float point number or 0xXXXXXXXX or 0xXXXXXXXXXXXXXXXX:0x3E000000
    //
    //f=0.125
    //hex=3E 00 00 00
    //bin=00111110000000000000000000000000
    //bin=0 01111100   00000000000000000000000
    //    + 124 -127 1.00000000000000000000000
    //    + -3       1.00000000000000000000000
    //
    //Input a float point number or 0xXXXXXXXX or 0xXXXXXXXXXXXXXXXX:0.125
    //f=0.125
    //hex=3E 00 00 00
    //bin=00111110000000000000000000000000
    //bin=0 01111100   00000000000000000000000
    //    + 124 -127 1.00000000000000000000000
    //    + -3       1.00000000000000000000000
    //
    //d=0.125
    //hex=3F C0 00 00 00 00 00 00
    //bin=0011111111000000000000000000000000000000000000000000000000000000
    //bin=0 01111111100   0000000000000000000000000000000000000000000000000000
    //    + 1020  -1023 1.0000000000000000000000000000000000000000000000000000
    //    + -3          1.0000000000000000000000000000000000000000000000000000
    //
    //Input a float point number or 0xXXXXXXXX or 0xXXXXXXXXXXXXXXXX:
    //
    
    
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
    1人已打赏

报告相同问题?

问题事件

  • 系统已结题 12月28日
  • 已采纳回答 12月20日
  • 创建了问题 12月18日

悬赏问题

  • ¥20 西门子S7-Graph,S7-300,梯形图
  • ¥50 用易语言http 访问不了网页
  • ¥50 safari浏览器fetch提交数据后数据丢失问题
  • ¥15 matlab不知道怎么改,求解答!!
  • ¥15 永磁直线电机的电流环pi调不出来
  • ¥15 用stata实现聚类的代码
  • ¥15 请问paddlehub能支持移动端开发吗?在Android studio上该如何部署?
  • ¥20 docker里部署springboot项目,访问不到扬声器
  • ¥15 netty整合springboot之后自动重连失效
  • ¥15 悬赏!微信开发者工具报错,求帮改