当前位置: 首页 > news >正文

C语言编程机器码转真值,【转载】IEEE754浮点数的表示方法

转载:http://blog.sina.com.cn/s/blog_97b4973a0101j9eo.html

1.浮点数的存储格式

浮点数在C/C++中对应float和double类型,我们有必要知道浮点数在计算机中实际存储的内容。

IEEE754标准中规定float单精度浮点数在机器中表示用 1 位表示数字的符号,用

8 位来表示指数,用23 位来表示尾数,即小数部分。对于double双精度浮点数,用 1 位表示符号,用

11 位表示指数,52 位表示尾数,其中指数域称为阶码。IEEE 浮点值的格式如下图所示。

a4c26d1e5885305701be709a3d33442f.png

注意,IEE754规定浮点数的阶码E采用指数”e的移码-1”来表示,请记住这一点。为什么指数移码要减去1,这是IEEE754对阶码的特殊要求,以满足特殊情况,比如对正无穷的表示。

2.浮点数的规格化

若不对浮点数的表示作出明确的规定,同一个浮点数的表示就不是唯一的。例如(1.75)10可以表示成1.11×21,0.111×21,0.0111×22等多种形式。当尾数不为0时,尾数域的最高有效位为1,这称为浮点数的规格化。否则,以修改阶码同时左右移动小数点位置的办法,使其标称规格化数的形式。

2.1单精度浮点数真值

IEEE754标准中,一个规格化32位的浮点数x的真值表示为:

x=(−1)S×(1.M)×2e

e=E−127

其中尾数域表示的值是1.M。因为规格化的浮点数的尾数域最左位总是1,故这一位不予存储,而认为隐藏在小数点的左边。

在计算指数e时,对阶码E的计算采用源码的计算方式,因此32位浮点数的8bits的阶码E的取值范围是0到255。其中当E为全0或者全1时,是IEEE754规定的特殊情况,下文会另外说明。

2.1双精度浮点数真值

64位的浮点数中符号为1位,阶码域为11位,尾数域为52位,指数偏移值是1023。因此规格化的64位浮点数x的真值是:

x=(−1)S×(1.M)×2e

e=E−1023

3.移码

移码(又叫增码)是对真值的补码的符号位取反,就可得到移码,一般用做浮点数的阶码,引入的目的是为了便于浮点数运算时的对阶操作。

对于定点整数,计算机一般采用补码的来存储。正整数的符号位为0,反码和补码等同于源码。

负整数符号位都固定为1,源码,反码和补码的表示都不相同,由原码表示法变成反码和补码有如下规则:(1)源码符号位为1不变,整数的每一位二进制数位求反得反码;(2)反码符号位为1不变,反码数值位最低位加

1得补码。

比如,以一个字节8bits来表示-3,那么[−3]原=10000011,[−3]反=11111100,[−3]补=11111101,那么-3的移码就是[−3]移=01111101。

如何将移码转换为真值-3呢?先将移码转换为补码,再求值。

4.浮点数的具体表示

4.1十进制到机器码

(1)0.50.5=(0.1)2,符号位S为0,指数为e=−1,规格化后尾数为1.0。

单精度浮点数尾数域共23位,右侧以0补全,尾数域:

M=[00000000000000000000000]2

阶码E:

E=[−1]移−1=[01111111]2−1=[01111110]2

对照单精度浮点数的存储格式,将符号位S,阶码E和尾数域M存放到指定位置,得0.5的机器码:

0.5=[00111111000000000000000000000000]2

十六进制表示为0.5=0x3f000000。

(2)1.5

1.5=[1.1]2,符号位为0,指数e=0,规格化后尾数为1.1。

尾数域M右侧以0补全,得尾数域:

M=[1

0000000000000000000000]2

阶码E:

E=[0]移−1=[10000000]2−1=[01111111]2

得1.5的机器码:

1.5=[00111111110000000000000000000000]2

十六进制表示为1.5=0x3fc00000。

(3)-12.5−12.5=[−1100.1]2,符号位S为1,指数e为3,规格化后尾数为1.1001,

尾数域M右侧以0补全,得尾数域:

M=[10010000000000000000000]2

阶码E:

E=[3]移−1=[10000011]2−1=[10000010]2

即-12.5的机器码:

−12.5=[11000001010010000000000000000000]2

十六进制表示为-12.5=0xc1480000。

用如下程序验证上面的推算,代码编译运行平台Win32+VC++ 2012:

#include

usingnamespacestd;

intmain(){

floata=0.5;

floatb=1.5;

floatc=-12.5;

unsignedint* pa=NULL;

pa=(unsignedint*)&a;

unsignedint* pb=NULL;

pb=(unsignedint*)&b;

unsignedint* pc=NULL;

pc=(unsignedint*)&c;

cout<

cout<<"b=0x"<

cout<

return0;

}

输出结果:a4c26d1e5885305701be709a3d33442f.png

验证正确。

4.2机器码到十进制

(1)若浮点数x的IEEE754标准存储格式为0x41360000,那么其浮点数的十进制数值的推演过程如下:

0x41360000=[01000001001101100000000000000000]

根据该浮点数的机器码得到符号位S=0,指数e=阶码-127=1000 0010-127=130-127=3。

注意,根据阶码求指数时,可以像上面直接通过

“阶码-127”求得指数e,也可以将阶码+1=移码,再通过移码求其真值便是指数e。比如上面阶码10000010+1=10000011[移码]=>00000011[补]=3(指数e)。

包括尾数域最左边的隐藏位1,那么尾数1.M=1.011 0110 0000 0000 0000

0000=1.011011。

于是有:

x=(−1)S×1.M×2e=+(1.011011)×23=+1011.011=(11.375)10

通过代码同样可以验证上面的推算:

#include

usingnamespacestd;

intmain(){

unsignedinthex=0x41360000;

float* fp=(float*)&hex;

cout<

return0;

}

输出结果:a4c26d1e5885305701be709a3d33442f.png

验证正确。

5.浮点数的几种特殊情况

(1)0的表示对于阶码为0或255的情况,IEEE754标准有特别的规定:如果

阶码E 是0 并且尾数M 是0,则这个数的真值为±0(正负号和数符位有关)。

因此+0的机器码为:0

00000000 000 0000 0000 0000 0000。-0的机器码为:1 00000000 000 0000 0000 0000

0000。

(2)+∞和−∞的表示如果

阶码E =

255 并且尾数M全是0,则这个数的真值为±∞(同样和符号位有关)。因此+∞的机器码为:0

11111111 000 0000 0000 0000 0000。-∞的机器吗为:1 11111111 000 0000 0000 0000

0000。

(3)NaN(Not

a Number)如果

E = 255 并且 M 不是0,则这不是一个数(NaN)。

6.浮点数的精度和数值范围

6.1浮点数的数值范围

根据上面的探讨,浮点数可以表示-∞到+∞,这只是一种特殊情况,显然不是我们想要的数值范围。

以32位单精度浮点数为例,阶码E由8位表示,取值范围为0-255,去除0和255这两种特殊情况,那么指数e的取值范围就是1-127=-126到254-127=127。

(1)最大正数因此单精度浮点数最大正数值的符号位S=0,阶码E=254,指数e=254-127=127,尾数M=111 1111 1111 1111 1111 1111,其机器码为:0

11111110 111 1111 1111 1111 1111 1111。

那么最大正数值:

PosMax=(−1)S×1.M×2e=+(1.11111111111111111111111)×2127≈3.402823e+38

这是一个很大的数。

(2)最小正数最小正数符号位S=0,阶码E=1,指数e=1-127=-126,尾数M=0,其机器码为0

00000001 000 0000 0000 0000 0000 0000。

那么最小正数为:

PosMin=(−1)S×1.M×2e=+(1.0)×2−126≈1.175494e−38

这是一个相当小的数。几乎可以近似等于0。当阶码E=0,指数为-127时,IEEE754就是这么规定1.0×2−127近似为0的,事实上,它并不等于0。

(3)最大负数最大负数符号位S=1,阶码E=1,指数e=1-127==-126,尾数M=0,机器码与最小正数的符号位相反,其他均相同,为:1 00000001 000 0000 0000 0000 0000

0000。

最大负数等于:

NegMax=(−1)S×1.M×2e=−(1.0)×2−126≈−1.175494e−38

(4)最小负数符号位S=0,阶码E=254,指数e=254-127=127,尾数M=111 1111 1111 1111 1111 1111,其机器码为:1

11111110 111 1111 1111 1111 1111 1111。

计算得:

NegMin=(−1)S×1.M×2e=+(1.11111111111111111111111)×2127=−3.402823e+38

6.2浮点数的精度

说道浮点数的精度,先给精度下一个定义。浮点数的精度是指浮点数的小数位所能表达的位数。

阶码的二进制位数决定浮点数的表示范围,尾数的二进制位数表示浮点数的精度。以32位浮点数为例,尾数域有23位。那么浮点数以二进制表示的话精度是23位,23位所能表示的最大数是223−1=8388607,所以十进制的尾数部分最大数值是8388607,也就是说尾数数值超过这个值,float将无法精确表示,所以float最多能表示小数点后7位,但绝对能保证的为6位,也即float的十进制的精度为为6~7位。

64位双精度浮点数的尾数域52位,因252−1=4,503,599,627,370,495,所以双精度浮点数的十进制的精度最高为16位,绝对保证的为15位,所以double的十进制的精度为15~16位。。

7.小结

本文操之过急,但也花了将近一天的时间,难免出现编辑错误和不当说法,请网友批评指正。不明之处,欢迎留言交流。对浮点数的乘法、除法运算还未涉及,后续可能会去学习并记录学习所得,与大家分享。

参考文献

相关文章:

  • c语言题加密文件,请高手指教!C语言文件加密题!
  • linux machine start,linux中MACHINE_STARTEND在9g10ek上实现
  • android设置按钮大小为屏幕百分比,android – 设置UI元素的位置/大小为屏幕大小的百分比...
  • android4.1用哪个ndk编译,androidstudio中用ndk编译的问题
  • 海美迪盒子android升级,海美迪4K播放器直升安卓7.0 画质再上新境界
  • android 手势旋转,android中手势操作图片的平移、缩放、旋转
  • 微信分身 android,微信分身版安卓版
  • android的设备节点,无法打开设备节点android
  • html加载图标的xpath位置,在格式不正确的HTML中使用XPath查找节点(或...
  • html 布局 id class,不使用class和id进行网页布局的方法
  • html画布模板,html2canvas.js
  • 川信计算机组装维护,凉山州中学生技能大赛信息技术类竞赛总结
  • 计算机应用基础_在线作业_e,计算机应用基础_在线作业_E.doc
  • 会计电算化的过程 实质上是用计算机,河南电大会计学专科《社会实践(会专)》(教考一体化)网上考试试题及答案...
  • html輸出excel,Javascript HTML表單table輸出Excel
  • 【Linux系统编程】快速查找errno错误码信息
  • 002-读书笔记-JavaScript高级程序设计 在HTML中使用JavaScript
  • Docker 笔记(2):Dockerfile
  • Essential Studio for ASP.NET Web Forms 2017 v2,新增自定义树形网格工具栏
  • input实现文字超出省略号功能
  • Invalidate和postInvalidate的区别
  • Linux编程学习笔记 | Linux多线程学习[2] - 线程的同步
  • Median of Two Sorted Arrays
  • Spark in action on Kubernetes - Playground搭建与架构浅析
  • Theano - 导数
  • vue-cli在webpack的配置文件探究
  • windows-nginx-https-本地配置
  • XForms - 更强大的Form
  • 对话 CTO〡听神策数据 CTO 曹犟描绘数据分析行业的无限可能
  • 京东美团研发面经
  • 一个SAP顾问在美国的这些年
  • 2017年360最后一道编程题
  • PostgreSQL 快速给指定表每个字段创建索引 - 1
  • RDS-Mysql 物理备份恢复到本地数据库上
  • 你学不懂C语言,是因为不懂编写C程序的7个步骤 ...
  • 如何用纯 CSS 创作一个菱形 loader 动画
  • ​RecSys 2022 | 面向人岗匹配的双向选择偏好建模
  • #pragma pack(1)
  • #快捷键# 大学四年我常用的软件快捷键大全,教你成为电脑高手!!
  • #每天一道面试题# 什么是MySQL的回表查询
  • (Redis使用系列) Springboot 使用Redis+Session实现Session共享 ,简单的单点登录 五
  • (笔试题)分解质因式
  • (附表设计)不是我吹!超级全面的权限系统设计方案面世了
  • (附源码)ssm高校社团管理系统 毕业设计 234162
  • (九)信息融合方式简介
  • (每日持续更新)jdk api之FileReader基础、应用、实战
  • (转载)利用webkit抓取动态网页和链接
  • .halo勒索病毒解密方法|勒索病毒解决|勒索病毒恢复|数据库修复
  • .NET 8.0 中有哪些新的变化?
  • .NET Core 版本不支持的问题
  • .net6+aspose.words导出word并转pdf
  • /etc/X11/xorg.conf 文件被误改后进不了图形化界面
  • @NoArgsConstructor和@AllArgsConstructor,@Builder
  • [BUUCTF 2018]Online Tool
  • [C#]winform制作圆形进度条好用的圆环圆形进度条控件和使用方法