日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

IEEE-754标准(32位) 十六进制转换十进制浮点数

發布時間:2023/11/27 生活经验 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 IEEE-754标准(32位) 十六进制转换十进制浮点数 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

因實驗需要,讀取陀螺儀的數據是16進制的數據,需要將該數據轉化為10進制方便自己查看,理解。記錄如下:

1.將(32位)16進制IEEE-754標準浮點數就是用十六進制表示浮點,稱為單精度浮點數。

?float類型在內存中占4個字節(32位),最高位用于表示符號;在剩下的31位中,從右向左了8位用于表示指數,其余用于表示尾數。(一個字節是8位)

對應關系如下:

符號位????指數位????尾數位

1位???????8位???????23位

舉例:(1)IEEE-754標準浮點數表示為 404FC593 H(H表示是16進制;)

(2)已知一個數為2.5,IEEE-754標準浮點數表示為 40200000H。
16進制浮點數與十進制的轉化步驟:
1、轉換為二進制 0 10000000 10011111100010110010011
2、其第0位 為符號位,為0則表示正數,反之1為復數,其讀數值用 s 表示;
3、第1~8位為冪數,其讀數值用 e 表示;
4、第9~31位共23位作為系數,視為二進制純小數,假定該小數的十進制值為 x
則按照規定,該浮點數的值用十進制表示為:= (-1)^s * (1 + x) * 2^(e - 127)

2.冪數的計算

10000000 轉換為十進制 128

3.系數的計算

二進制對應的位數的數*2的負位置,再相加
10011111100010110010011

1 1 * 2^(-1)
0 0 * 2^(-2)
0 0 * 2^(-3)
1 1 * 2^(-4)
... ...
1 1 * 2^(-23)
相加可得
0.62321698665618896

4.十進制最后換算

(-1)^0 * (1+ 0.62321698665618896) * 2^(128-127) = 3.246433973312378

舉例:

16進制浮點數與十進制的轉化步驟:
對于大小為32-bit的浮點數(32-bit為單精度,64-bit浮點數為雙精度,80-bit為擴展精度浮點數),
1、其第31 bit為符號位,為0則表示正數,反之為復數,其讀數值用s表示;
2、第30~23 bit為冪數,其讀數值用e表示;
3、第22~0 bit共23 bit作為系數,視為二進制純小數,假定該小數的十進制值為x;
則按照規定,該浮點數的值用十進制表示為:= (-1)^s * (1 + x) * 2^(e - 127)

例如:對于16進制浮點數49E48E68H來說,如圖5:


1、其第31 bit為符號位,為0則表示為正數;(左邊是高位,右邊是低位)
2、第30~23 bit依次為100 1001 1,讀成十進制就是147,即e = 147。
3、第22~0 bit依次為110 0100 1000 1110 0110 1000,也就是二進制的純小數0.110 0100 1000 1110 0110 1000,其十進制形式為0.78559589385986328125,即x = 0.78559589385986328125。即x = 0.78559589385986328125。

可知:16進制浮點數49E48E68H的10進制表示:
=(-1)^s * (1 + x) * 2^(e - 127)
=(-1)^0 * (1+ 0.78559589385986328125) * 2^(147-127) = 1872333。

下面是實現的代碼如下所示:

#include <stdio.h>
#include <math.h>
//十六進制數轉浮點數通用方法
float Hex2Float(unsigned long number)
{unsigned int sign = (number & 0x80000000) ? -1 : 1;//三目運算符unsigned int exponent = ((number >> 23) & 0xff) - 127;//先右移操作,再按位與計算,出來結果是30到23位對應的efloat mantissa = 1 + ((float)(number & 0x7fffff) / 0x7fffff);//將22~0轉化為10進制,得到對應的xreturn sign * mantissa * pow(2, exponent);
}
//測試用例
int main()
{unsigned long a = 0x404FC593;//16進制404FC593float result = Hex2Float(a);printf("result = %f \n", result);return 0;
}

結果如下:

代碼解讀:(下邊number以49E48E68為例:)

? ??

(1)首先將number與16進制的8000 0000 做按位與預算,因為16進制8000 0000的二進制除了32位是1之外其他都是0(任何數與0按位與都是0),所以按位與計算是為了得到符號位。

按位與操作規則:?按位與操作 0&0=0; 0&1=0; 1&0=0; 1&1=1

再進行三目運算符操作:括號內表達式非0的話就取-1,是0的話就取1。最終得到符號位。

C語言三目運算符用法:

對于條件表達式b ? x : y,先計算條件b,然后進行判斷。如果b的值為true,計算x的值,運算結果為x的值;否則,計算y的值,運算結果為y的值。

(2)右移操作:https://blog.csdn.net/weixin_42216574/article/details/82885102

?左移運算符(<<)

  • 將一個運算對象的各二進制位全部左移若干位(左邊的二進制位丟棄,右邊補0)。

  • 例:a = a << 2 將a的二進制位左移2位,右補0,

  • 左移1位后a = a * 2;

  • 若左移時舍棄的高位不包含1,則每左移一位,相當于該數乘以2。

右移運算符(>>),此處右移23位

  • 將一個數的各二進制位全部右移若干位,正數左補0,負數左補1,右邊丟棄。

  • 操作數每右移一位,相當于該數除以2。

    • 例如:a = a >> 2 將a的二進制位右移2位,
      左補0 or 補1 得看被移數是正還是負。
  • >> 運算符把 expression1 的所有位向右移 expression2 指定的位數。expression1 的符號位被用來填充右移后左邊空出來的位。向右移出的位被丟棄。

    • 例如,下面的代碼被求值后,temp 的值是 -4:
      var temp = -14 >> 2
      -14 (即二進制的 11110010)右移兩位等于 -4 (即二進制的 11111100)。
  • 無符號右移運算符(>>>)

  • >>> 運算符把 expression1 的各個位向右移 expression2 指定的位數。右移后左邊空出的位用零來填充。移出右邊的位被丟棄。

所以上述右移23位之后得到:

0000? 0000? 0000 0000? 0000 0000 1001 0011

右移完成之后再與16進制0xff做按位與運算。ff的二進制是(11111111),

00000000000000000000000010010011

按位與:? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?1? ?1? ?1? ? 1? ? 1? ? 1? ? 1? ? 1

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 得到:? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ????1? ?0? ?0? ? 1? ?0? ?0? ? 1? ? 1? ? ?

此步驟得到的就是1到8位,對應第二步。

? ( 3)再與0x7fffff做按位與運算。

?

------------------------------------------上邊的代碼對應的無符號數據,下邊是可以是有符號的:(使用的是unsigned long long 型,因為要考慮數據范圍)

char,short ,int ,long,long long,unsigned long long數據范圍

速查表:

char -128 ~ +127 (1 Byte)
short -32767 ~ + 32768 (2 Bytes)
unsigned short 0 ~ 65535 (2 Bytes)
int -2147483648 ~ +2147483647 (4 Bytes)
unsigned int 0 ~ 4294967295 (4 Bytes)
long == int
long long -9223372036854775808 ~ +9223372036854775807 (8 Bytes)
double 1.7 * 10^308 (8 Bytes)

unsigned int 0~4294967295
long long的最大值:9223372036854775807
long long的最小值:-9223372036854775808
unsigned long long的最大值:18446744073709551615

__int64的最大值:9223372036854775807
__int64的最小值:-9223372036854775808
unsigned __int64的最大值:18446744073709551615

#include <stdio.h>
#include <math.h>
#include <iostream>//十六進制數轉浮點數通用方法
float Hex2Float(unsigned long long number)
{std::cout << "number:" << number << std::endl;int sign = (number & 0x80000000) ? -1 : 1;//符號位std::cout << "符號位:" << sign << std::endl;int exponent = ((number >> 23) & 0xff) - 127;std::cout << "e位:" << exponent << std::endl;float mantissa = 1 + ((float)(number & 0x7fffff) / 0x7fffff);std::cout << "x位:" << mantissa <<std::endl;return sign * mantissa * pow(2, exponent);
}
//測試用例
int main()
{unsigned long long a = 0xBEAA2737;float result = Hex2Float(a);printf("result = %f \n", result);return 0;
}

結果是:

下面是參考另外一位博主的直接由32位的二進制轉化為10進制:

https://blog.csdn.net/qq_35353824/article/details/107773420#comments_14315438

IEEE-754標準(32位)十六進制轉十進制浮點數(其實下面第一個程序直接輸入的是二進制數)

#include<fstream>
#include <sstream>
#include <iostream>
#include<math.h>
using namespace std;double BtoD(string x)
{double ans;int E = 0;double D = 0;for (int i = 1; i < 32; i++){if (i < 9){E += (x[i] - '0') << (8 - i);//cout << E << endl;}else{D += (x[i] - '0') * pow(2 ,(8 - i));//cout << D << endl;}}ans = pow(2, E - 127)*(1+D);if (x[0] = '1')ans = -ans;return -ans;
}int main()
{string input;ifstream in;in.open("D:\\p1.txt");if (!in.good()){cout << "文件打開失敗" << endl;system("pause");return 0;}while (!in.eof()){in >> input;cout << input << endl;;cout << BtoD(input) << endl;system("pause");}in.close();cout << "轉換完成" << endl;system("pause");return 0;}

十進制浮點數 轉IEEE-754標準(32位)十六進制:

#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還是1while (!b == 0){if ((1.0 / n) < b){xiaoshu.push_back(1);//若為1則b減去該位所對應的十進制小數大小 ,繼續判斷低一位,直到b=0b = 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 1ite++;}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;}

?

總結

以上是生活随笔為你收集整理的IEEE-754标准(32位) 十六进制转换十进制浮点数的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 久久综合区 | 欧美日韩国产精品一区二区三区 | 97国产在线视频 | 亚洲成人免费网站 | 欧美极品在线视频 | 黄视频网站免费看 | 成人精品亚洲 | 欧美高h| 亚洲欧美偷拍视频 | 一级少妇毛片 | 黄色一级片免费看 | 国产一区二区h | 国产熟妇一区二区三区aⅴ网站 | 精品人人人 | 久久福利视频导航 | 亚洲论理 | 最全aⅴ番号库 | 久久婷婷av| 欧美色频 | 一本一道久久a久久精品综合 | 中文在线8资源库 | 最新av导航 | 性感少妇在线观看 | 强开小嫩苞一区二区三区网站 | 国产成人一区 | 天天插天天射 | 成年女人18级毛片毛片免费 | 9色av| av站 | 丁香久久 | 国产熟妇另类久久久久 | 97香蕉久久夜色精品国产 | 国产视频不卡一区 | 日韩无遮挡| 亚洲视频久久 | 国产美女精品视频 | 亚洲综合无码一区二区 | 激情婷婷在线 | 中文字幕一区二区人妻视频 | 久久精品片 | 精品免费在线观看 | 成人免费网站在线 | 中国性xxx | 色欧美综合| xxxxxx黄色 | 亚洲最大网 | 日本人dh亚洲人ⅹxx | 亚洲视频 欧美视频 | 女生张开腿让男生插 | 成人激情四射网 | 精品少妇人妻一区二区黑料社区 | 狠狠综合网 | 91视频入口| 精品国产1区2区 | 亚洲再线| 岛国精品一区二区三区 | 丰满岳跪趴高撅肥臀尤物在线观看 | 亚洲av无一区二区三区怡春院 | 91嫩草影视 | 男人av网站 | 五月天一区二区 | 五月天一区二区三区 | 永久av在线免费观看 | 搞逼综合网| 射黄视频 | 国产真实老熟女无套内射 | 蜜桃av成人| 国产破处在线 | 男人日女人b视频 | 精品在线视频免费观看 | 老熟女毛茸茸 | 日本一区二区三区视频在线 | 神宫寺奈绪一区二区三区 | 久久亚洲AV无码专区成人国产 | 性xxx18| 国产三级三级三级三级三级 | 男生吃小头头的视频 | 99久久成人| 香蕉黄色网 | 刘亦菲一区二区三区免费看 | 久久精品视频3 | 91高清在线视频 | www一级片 | 色国产视频 | 亚洲av永久纯肉无码精品动漫 | 奇米影视色 | 中文字幕在线观看视频一区 | 一区二区毛片 | 午夜性刺激免费视频 | 国产精品视频99 | 日本黄色短片 | 枫花恋在线观看 | 国产少女免费观看高清 | 69xx国产| 毛片综合 | 男人操女人动态图 | 午夜裸体性播放 | 日本伦理片在线播放 | 强开小受嫩苞第一次免费视频 |