0.667二进制浮点数的二进制转换形式

维基百科,自由的百科全书
二进制浮点数算术标准(IEEE
754)是1980年代以来最广泛使用的运算标准,为许多与所采用。这个标准定义了表示浮点数的格式(包括负零)与反常值(denormal
number)),一些特殊数值(与(NaN)),以及这些数值的“浮点数运算符”;它也指明了四种和五种例外状况(包括例外发生的时机与处理方式)。
IEEE 754规定了四种表示浮点数值的方式:单精确度(32位)、双精确度(64位)、延伸单精确度(43比特以上,很少使用)与延伸双精确度(79比特以上,通常以80比特实做)。只有32位模式有强制要求,其他都是选择性的。大部分都有提供IEEE浮点数格式与算术,但有些将其列为非必需的。例如,IEEE
754问世之前就有的,现在有包括IEEE算术,但不算作强制要求(C语言的float通常是指IEEE单精确度,而double是指双精确度)。
该标准的全称为IEEE二进制浮点数算术标准(ANSI/IEEE Std 754-1985),又称IEC ,微处理器系统的二进制浮点数算术(本来的编号是IEC 559:1989)。后来还有“与基数无关的浮点数”的“IEEE
854-1987标准”,有规定基数为2跟10的状况。现在最新标准是“IEEE 854-2008标准”。
在六、七十年代,各家计算机公司的各个型号的计算机,有着千差万别的浮点数表示,却没有一个业界通用的标准。这给数据交换、计算机协同工作造成了极大不便。IEEE的浮点数专业小组于七十年代末期开始酝酿浮点数的标准。在1980年,就推出了单片的8087浮点数协处理器,其浮点数表示法及定义的运算具有足够的合理性、先进性,被IEEE采用作为浮点数的标准,于1985年发布。而在此前,这一标准的内容已在八十年代初期被各计算机公司广泛采用,成了事实上的业界工业标准。
以下是该标准对浮点数格式的描述。
把W个(bit)的数据,从内存地址低端到高端,以0到W-1编码。通常将内存地址低端的比特写在最右边,称作(least
significant bit或lsb),代表最小的比特,改变时对整体数值影响最小的比特。声明这一点的必要性在于X86体系架构是的数据存储。
对于十进制整数N,必要时表示为N10以与二进制的数的表示N2相区分。
对于一个数,其二进制表示下的指数的值,下文称之为指数的实际值;而根据IEEE 754标准对指数部分的编码的值,称之为浮点数表示法指数域的编码值。
IEEE 754浮点数的三个域
二进制浮点数是以的格式存储——被指定为(sign
bit);“指数部份”,即次高有效的e个比特,存储指数部分;最后剩下的f个低有效位的比特,存储“尾数”(significand)的小数部份(在非规约形式下整数部份默认为0,其他情况下一律默认为1)。
指数偏移值(exponent bias),是指浮点数表示法中的指数域的编码值为指数的实际值加上某个固定的值,IEEE 754标准规定该固定值为 2e-1&- 1,其中的e为存储指数的比特的长度。
以单精度浮点数为例,它的指数域是8个比特,固定偏移值是28-1&- 1 = 128-1 = 127. 单精度浮点数的指数部分实际取值是从128到-127。例如指数实际值为1710,在单精度浮点数中的指数域编码值为14410, 即14410&= 1710&+ 12710.
采用指数的实际值加上固定的偏移值的办法表示浮点数的指数,好处是可以用长度为e个比特的无符号整数来表示所有的指数取值,这使得两个浮点数的指数大小的比较更为容易。
如果浮点数中指数部分的编码值在&exponent&之间,且尾数部分最高有效位(即整数字)是1,那么这个浮点数将被称为规约形式的浮点数。
如果浮点数的指数部分的编码值是0,尾数的最高有效位(即整数字)也是0,那么这个浮点数将被称为非规约形式的浮点数。IEEE 754标准规定:非规约形式的浮点数的指数偏移值比规约形式的浮点数的指数偏移值大1. 例如,最小的规约形式的单精度浮点数的指数部分编码值为1,指数的实际值为-126;而非规约的单精度浮点数的指数域编码值为0,对应的指数实际值也是-126而不是-127。实际上非规约形式的浮点数仍然是有效可以使用的,只是它们的绝对值已经小于所有的规约浮点数的绝对值;即所有的非规约浮点数比规约浮点数更接近0。规约浮点数的尾数大于等于1且小于2,而非规约浮点数的尾数小于1且大于0.
IEEE 754-1985标准采用非规约浮点数,源于70年代末IEEE浮点数标准化专业技术委员会酝酿浮点数二进制标准时,对渐进式下溢出(gradual underflow)的力荐。当时十分流行的&机的浮点数表示采用了突然式下溢出(abrupt
underflow). 如果没有渐进式下溢出,那么0与绝对值最小的浮点数之间的距离(gap)将大于相邻的小浮点数之间的距离。例如单精度浮点数的绝对值最小的规约浮点数是,
它与绝对值次小的规约浮点数之间的距离为。如果不采用渐进式下溢出,那么绝对值最小的规约浮点数与0的距离是相邻的小浮点数之间距离的倍!可以说是非常突然的下溢出到0。这种情况的一种糟糕后果是:两个不等的小浮点数X与Y相减,结果将是0.
训练有素的数值分析人员可能会适应这种限制情况,但对于普通的程序员就很容易陷入错误了。采用了渐进式下溢出后将不会出现这种情况。例如对于单精度浮点数,指数部分实际最小值是(-126),对应的尾数部分从,&一直到,&,相邻两小浮点数之间的距离(gap)都是;而与0最近的浮点数(即最小的非规约数)也是。
这里有三个特殊值需要指出:
如果&指数&是0 并且尾数的&小数部分&是0,这个数±0(和符号位相关)如果&指数&=&&并且尾数的&小数部分&是0,这个数是 ±(同样和符号位相关)如果&指数&=&&并且尾数的&小数部分&非0,这个数表示为。
以上规则,总结如下:
非规约形式
单精度二进制小数,使用32个比特存储。
偏正值 (实际的指数大小+127)
至 位编号(从右边开始为0)
S为符号位,Exp为指数字,Fraction为有效数字。 指数部分即使用所谓的偏正值形式表示,偏正值为实际的指数大小与一个固定值(32位的情况是127)的和。采用这种方式表示的目的是简化比较。因为,指数的值可能为正也可能为负,如果采用补码表示的话,全体符号位S和Exp自身的符号位将导致不能简单的进行大小比较。正因为如此,指数部分通常采用一个无符号的正数值存储。单精度的指数部分是-126~+127加上偏移&# ,指数值的大小从1~254(0和255是特殊值)。浮点小数计算时,指数值减去偏正值将是实际的指数大小。
单精度浮点数各种极值情况:
有偏移指数
数值
最小的非规约数
±2-23&× 2-126&= ±2-149&≈ ±1.4×10-45
中间大小的非规约数
±2-1&× 2-126&= ±2-127&≈ ±5.88×10-39
最大的非规约数
±(1-2-23) × 2-126&≈ ±1.18×10-38
最小的规约数
±2-126&≈ ±1.18×10-38
最大的规约数
±(2-2-23) × 2127&≈ ±3.4×1038
* 符号位可以为0或1&.
二进制小数,使用64个比特存储。
偏正值 (实际的指数大小+1023)
至 位编号(从右边开始为0)
S 为符号位,Exp为指数字,Fraction为有效数字。 指数部分即使用所谓的偏正值形式表示,偏正值为实际的指数大小与一个固定值(64位的情况是1023)的和。采用这种方式表示的目的是简化比较。因为,指数的值可能为正也可能为负,如果采用补码表示的话,全体符号位S和Exp自身 的符号位将导致不能简单的进行大小比较。正因为如此,指数部分通常采用一个无符号的正数值存储。双精度的指数部分是-1022~+1023加上1023 ,指数值的大小从1~进位全为0)和2047(2进位全为1)是特殊值)。浮点小数计算时,指数值减去偏正值将是实际的指数大小。
浮点数基本上可以按照符号位、指数域、尾数域的顺序作字典比较。显然,所有正数大于负数;正负号相同时,指数的二进制表示法更大的其浮点数值更大。
任何有效数上的运算结果,通常都存放在较长的暂存器中,当结果被放回浮点格式时,必须将多出来的比特丢弃。 有多种方法可以用来运行舍入作业,实际上IEEE标准列出4种不同的方法:
舍入到最接近:会将结果舍入为最接近且可以表示的值。这是缺省的近似方法。朝+∞方向舍入:会将结果朝正无限大的方向舍入。朝-∞方向舍入: 会将结果朝负无限大的方向舍入。朝0方向舍入: 会将结果朝0的方向舍入。
下述函数必须提供:
加减乘除 Add, subtract, multiply, divide平方根 Square root浮点余数. 返回值 x-(round(x/y)*y).近似到最近的整数. 如果恰好在两个相邻整数之间,则近似到偶数.比较运算. IEEE754定义了特殊情况: -inf = -inf, inf = inf and x ≠ NaN for any x (including NaN).
Under some C compilers,&copysign(x,y)&returns x with the sign of y, so&abs(x)&equals&copysign(x,1.0).
This is one of the few operations which operates on a NaN in a way resembling arithmetic. The function&copysign&is new in the C99 standard.-x returns x with the sign reversed. This is different from 0-x in some cases, notably when x is 0. So -(0) is -0, but the sign of 0-0 depends on the rounding mode.scalb(y, N)logb(x)finite(x)&a&&for
&x is a finite value&, equivalent to -Inf & x & Infisnan(x)&a predicate for &x is a nan&, equivalent to &x ≠ x&x && y&which turns out to have different exception behavior than NOT(x = y).unordered(x, y)&is true when &x is unordered with y&, i.e., either x or y is a NaN.class(x)nextafter(x,y)&returns the next representable value from x in the direction towards y
&- a good introduction and explanation.&History and minutes
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:239422次
积分:3329
积分:3329
排名:第4905名
原创:73篇
转载:110篇
评论:43条
(1)(1)(1)(1)(1)(1)(2)(2)(3)(1)(2)(1)(1)(1)(1)(1)(2)(4)(5)(1)(1)(2)(1)(2)(3)(6)(2)(14)(4)(12)(7)(4)(7)(3)(6)(3)(3)(6)(5)(5)(9)(4)(28)(13)请将十进制数0.07525表示为规格化浮点数,阶码(包括阶符)为4位二进制位,_百度知道
请将十进制数0.07525表示为规格化浮点数,阶码(包括阶符)为4位二进制位,
尾数(包括)尾符为8位二进制数,均采用补码形式
提问者采纳
十进制的小数转化为二进制的数,方法为:乘2取整法,即将小数部分乘以2,然后取整数部分,剩下的小数部分继续乘以2,然后取整数部分,剩下的小数部分又乘以2,一直取到小数部分 为零为止。如果永远不能为零,就同十进制数的四舍五入一样,按照要求保留多少位小数时,就根据后面一位是0还是1,取舍,如果是零,舍掉,如果是1,向入一位。换句话说就是0舍1入。举例:22.8125转二进制,这样计算:整数和小数分别转换。整数除以2,商继续除以2,得到0为止,将余数逆序排列。22 / 2
11 余011/2
余 1所以22的二进制是10110小数乘以2,取整,小数部分继续乘以2,取整,得到小数部分0为止,将整数顺序排列。0..625 取整1,小数部分是0.6250.625x2=1.25 取整1,小数部分是0.250.25x2=0.5 取整0,小数部分是0.50.5x2=1.0 取整1,小数部分是0,结束所以0.8125的二进制是0.1101十进制22.8125等于二进制所以,0.07525表示成二进制是:0..1505
00.301*2=0.602
00.602*2=1.204
10.204*2=0.408
00.408*2=0.816
00.816*2=1.632
10.632*2=1.264
10.264*2=0.528
00.528*2=1.056
10.056*2=0.112
00.112*2=0.224
00.224*2=0.448
00.0=1.^-3(由于你的需求是:尾数(包括)尾符为8位二进制数)所以,0.07525(十进制)=1.^-3(二进制)阶码=-3+127=124符号位 指数部分 尾数部分0 10100
提问者评价
采纳率100%
其他类似问题
为您推荐:
浮点数的相关知识
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁9104人阅读
int和float都是4字节32位表示形式。为什么float的范围大于int?
float精度为6~7位。1.66*10^10的数字结果并不是166
指数越大,误差越大。
这些问题,都是浮点数的存储方式造成的。 &
& & float和double在存储方式上都是遵从IEEE的规范的,float遵从的是IEEE R32.24 ,而double 遵从的是R64.53。
&&& 无论是单精度还是双精度在存储中都分为三个部分:
符号位(Sign) : 0代表正,1代表为负 指数位(Exponent):用于存储科学计数法中的指数数据,并且采用移位存储 尾数部分(Mantissa):尾数部分
其中float的存储方式如下图所示:
而双精度的存储方式为:
& &&&&&将一个float型转化为内存存储格式的步骤为:
&&&&&(1)先将这个实数的绝对值化为二进制格式。&
&&&& (2)将这个二进制格式实数的小数点左移或右移n位,直到小数点移动到第一个有效数字的右边。&
&&&& (3)从小数点右边第一位开始数出二十三位数字放入第22到第0位。&
&&&& (4)如果实数是正的,则在第31位放入“0”,否则放入“1”。&
&&&& (5)如果n 是左移得到的,说明指数是正的,第30位放入“1”。如果n是右移得到的或n=0,则第30位放入“0”。&
&&&& (6)如果n是左移得到的,则将n减去1后化为二进制,并在左边加“0”补足七位,放入第29到第23位。如果n是右移得到的或n=0,则将n化为二进制后在左边加“0”补足七位,再各位求反,再放入第29到第23位。
&&&& R32.24和R64.53的存储方式都是用科学计数法来存储数据的,比如8.25用十进制的科学计数法表示就为:8.25*,而120.5可以表示为:1.205*,计算机根本不认识十进制的数据,他只认识0,1,所以在计算机存储中,首先要将上面的数更改为二进制的科学计数法表示,8.25用二进制表示可表示为.5用二进制表示为:用二进制的科学计数法表示1000.01可以表示为1.0.1可以表示为1.1101101*,任何一个数都的科学计数法表示都为1.xxx*,尾数部分就可以表示为xxxx,第一位都是1嘛,干嘛还要表示呀?可以将小数点前面的1省略,所以23bit的尾数部分,可以表示的精度却变成了24bit,道理就是在这里,那24bit能精确到小数点后几位呢,我们知道9的二进制表示为1001,所以4bit能精确十进制中的1位小数点,24bit就能使float能精确到小数点后6位,而对于指数部分,因为指数可正可负,8位的指数位能表示的指数范围就应该为:-127-128了,所以指数部分的存储采用移位存储,存储的数据为元数据+127,下面就看看8.25和120.5在内存中真正的存储方式。
&&&& 首先看下8.25,用二进制的科学计数法表示为:1.0001*
按照上面的存储方式,符号位为:0,表示为正,指数位为:3+127=130 ,位数部分为,故8.25的存储方式如下图所示:
而单精度浮点数120.5的存储方式如下图所示:
& & &&将一个内存存储的float二进制格式转化为十进制的步骤:&
&&&& (1)将第22位到第0位的二进制数写出来,在最左边补一位“1”,得到二十四位有效数字。将小数点点在最左边那个“1”的右边。&
&&&& (2)取出第29到第23位所表示的值n。当30位是“0”时将n各位求反。当30位是“1”时将n增1。&
&&&& (3)将小数点左移n位(当30位是“0”时)或右移n位(当30位是“1”时),得到一个二进制表示的实数。&
&&&& (4)将这个二进制实数化为十进制,并根据第31位是“0”还是“1”加上正号或负号即可。
那么如果给出内存中一段数据,并且告诉你是单精度存储的话,你如何知道该数据的十进制数值呢?其实就是对上面的反推过程,比如给出如下内存数据:0000,首先我们现将该数据分段,0
110 00 ,在内存中的存储就为下图所示:
根据我们的计算方式,可以计算出,这样一组数据表示为:1.0.5
而双精度浮点数的存储和单精度的存储大同小异,不同的是指数部分和尾数部分的位数。所以这里不再详细的介绍双精度的存储方式了,只将120.5的最后存储方式图给出,大家可以仔细想想为何是这样子的
下面我就这个基础知识点来解决一个我们的一个疑惑,请看下面一段程序,注意观察输出结果
&&&&&&&&&&& float f = 2.2f;
&&&&&&&&&&& double d = (double)f;
&&&&&&&&&&& Console.WriteLine(d.ToString(&0.0&));
&&&&&&&&&&& f = 2.25f;
&&&&&&&&&&& d = (double)f;
&&&&&&&&&&& Console.WriteLine(d.ToString(&0.0&));
可能输出的结果让大家疑惑不解,单精度的2.2转换为双精度后,精确到小数点后13位后变为了2.7,而单精度的2.25转换为双精度后,变为了2.0,为何2.2在转换后的数值更改了而2.25却没有更改呢?很奇怪吧?其实通过上面关于两种存储结果的介绍,我们已经大概能找到答案。首先我们看看2.25的单精度存储方式,很简单 0 1 00 ,而2.25的双精度表示为:0 100 10 0000
00 00 00 ,这样2.25在进行强制转换的时候,数值是不会变的,而我们再看看2.2呢,2.2用科学计数法表示应该为:将十进制的小数转换为二进制的小数的方法为将小数*2,取整数部分,所以0.282=0.4,所以二进制小数第一位为0.4的整数部分0,0.4×2=0.8,第二位为0,0.8*2=1.6,第三位为1,0.6×2 = 1.2,第四位为1,0.2*2=0.4,第五位为0,这样永远也不可能乘到=1.0,得到的二进制是一个无限循环的排列
... ,对于单精度数据来说,尾数只能表示24bit的精度,所以2.2的float存储为:
但是这样存储方式,换算成十进制的值,却不会是2.2的,应为十进制在转换为二进制的时候可能会不准确,如2.2,而double类型的数据也存在同样的问题,所以在浮点数表示中会产生些许的误差,在单精度转换为双精度的时候,也会存在误差的问题,对于能够用二进制表示的十进制数据,如2.25,这个误差就会不存在,所以会出现上面比较奇怪的输出结果。
小数的二进制表示问题
&&&&&&&首先我们要搞清楚下面两个问题:
&&&& (1)& 十进制整数如何转化为二进制数
&&&&&&&&&& 算法很简单。举个例子,11表示成二进制数:
&&&&&&&&&&&&&&&&&&&& 11/2=5 & 余&& 1
&&&&&&&&&&&&&&&&&&&&&& 5/2=2&& 余&& 1
&&&&&&&&&&&&&&&&&&&&&& 2/2=1&& 余&& 0
&&&&&&&&&&&&&&&&&&&&&& 1/2=0&& 余&& 1
&&&&&&&&&&&&&&&&&&&&&&&&& 0结束&&&&&&&& 11二进制表示为(从下往上):1011
&&&&&&&&& 这里提一点:只要遇到除以后的结果为0了就结束了,大家想一想,所有的整数除以2是不是一定能够最终得到0。换句话说,所有的整数转变为二进制数的算法会不会无限循环下去呢?绝对不会,整数永远可以用二进制精确表示&,但小数就不一定了。
&&&&& (2) 十进制小数如何转化为二进制数
&&&&&&&&&& 算法是乘以2直到没有了小数为止。举个例子,0.9表示成二进制数
&&&&&&&&&&&&&&&&&&&& 0.9*2=1.8&& 取整数部分& 1
&&&&&&&&&&&&&&&&&&&& 0.8(1.8的小数部分)*2=1.6&&& 取整数部分& 1
&&&&&&&&&&&&&&&&&&&& 0.6*2=1.2&& 取整数部分& 1
&&&&&&&&&&&&&&&&&&&& 0.2*2=0.4&& 取整数部分& 0
&&&&&&&&&&&&&&&&&&&& 0.4*2=0.8&& 取整数部分& 0
&&&&&&&&&&&&&&&&&&&& 0.8*2=1.6 & 取整数部分& 1
&&&&&&&&&&&&&&&&&&&& 0.6*2=1.2&& 取整数部分& 0
&&&&&&&&&&&&&&&&&&&&&&&&&&&&& .........&&&&& 0.9二进制表示为(从上往下): 0......
&&&&&&&&&& 注意:上面的计算过程循环了,也就是说*2永远不可能消灭小数部分,这样算法将无限下去。很显然,小数的二进制表示有时是不可能精确的&。其实道理很简单,十进制系统中能不能准确表示出1/3呢?同样二进制系统也无法准确表示1/10。这也就解释了为什么浮点型减法出现了&减不尽&的精度丢失问题。
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:56031次
排名:千里之外
原创:14篇
转载:25篇
(1)(3)(1)(1)(3)(1)(4)(3)(4)(2)(4)(2)(2)(1)(3)(3)(2)汇编语言:如何将浮点数转换为二进制_百度知道
汇编语言:如何将浮点数转换为二进制
从键盘上输入一个浮点数(考虑单精度、双精度、扩展精度的情况)转换为二进制数,并保存在内存当中用MASM编写,怎样设计这个函数
你说从键盘上输入,那输入应该是一个字符串,例如 &1.23& 之类的如果像1楼那样自己实现IEEE标准的话是很麻烦的,因为要用到高精度算法。如果没要求自己实现浮点数标准(符号位、幂、尾数)的话,因为现在PC机的CPU基本都是用那个标准,所以我建议叫CPU来完成转化。下面例子为了方便用C语言表示例如输入是字符串 str = &123.456&double value = 0; // 初始化双精度数value为0依次扫描字符串 str = &123.456&小数点前面的整数是 &123&value = value * 10 + (str[0] - '0');value = value * 10 + (str[1] - '0');value = value * 10 + (str[2] - '0');现在 value = 123小数点后数就另外一种处理方法double p = 1;value += (str[4] - '0') * (p /= 10);value += (str[5] - '0') * (p /= 10);value += (str[6] - '0') * (p /= 10);这样 value 基本上等于 123.456.为什么说基本上,因为中间用了除法,可能导致精度丢失。或者你可以先让 value = 123456,然后 value 除以 1000,那样精度高一些。这个过程其实是字符串转为浮点数的过程,像C里的 scanf 函数。value 在计算机里就是按照IEEE标准存放的了
其他类似问题
为您推荐:
浮点数的相关知识
其他1条回答
IEEE浮点数规则,分符号位S,阶码E,尾数M。
长度float=S+E+M=1+8+23=32, double=1+11+52=64.
符号位0表示正,1表示负。
阶码可表达位移量,比如S=8, (2^8/2=256/2=128) ,可表达(127,-128),因为正数包含零所以是127. 为了不出现负数所以指数数值要加上127,数值左移为负,右移为正。
尾数即是位移后的数值。
Float 38414.4 二进制表示:
第一阶段:
38414.4 = 960E.66
计算如下:
150/16=9...6
38414 = 9_6_0_E =9*16^(3)+6*16^(2)+0*16^(1)+E*16^(0)
9 = 1_0_0_1 = 1*2^(3)+0*2^(2)+0*2^(1)+1*2(0)
以此类推,我这样计算的目的是顺便介绍十六进制的转换方法。
0.4*16=6.4=6...0.4
代码怎么写啊
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁将十进制数17.296875转换成IEEE754格式的32浮点数的二进制存储_百度知道
将十进制数17.296875转换成IEEE754格式的32浮点数的二进制存储
将十进制数17.296875转换成IEEE754格式的32浮点数的二进制存储
提问者采纳
将原始数据进行整数化:
(17.*(2^16)10
=(17.*(65536)10
&( //去掉小数,保留整数部分
=(114C00)16
因为最初乘了65536,即2的16次方,所以换算成二进制时应右移16位,去掉前导零,
即(00000)2
单精度浮点数保存的字节格式如下:
内容:SEEE EEEE
根据IEEE浮点数的定义,将上述二进制数规格化:
符号S为正,等于0 B;
指数EEEEEEEE为4+127=131,等于
尾数为 B;
若将上述值表示为十六进制数,则为(41 8A 60
提问者评价
来自团队:
其他类似问题
为您推荐:
ieee754的相关知识
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁

我要回帖

更多关于 浮点数转换为二进制 的文章

 

随机推荐