从IEEE754标准谈C语言浮点数据类型【vnsc5858威尼斯

时间:2019-08-02 12:56来源:计算机教程

先看下面几个问题,如果你能准确地回答,那么此篇文章将不适合你:

  • 计算机中怎样表示浮点数的,与整型的表示方法有什么不同?
  • 32位精度的float类型和64位精度的double类型能表示浮点数最大范围是多少?
  • 该C语言语句 printf("%dn", 2.5);  输出结果是什么,为什么?

我先说在此之前我如果回答,答案如下:

  • 计算机中有符号整型采用补码进行表示,浮点型怎么表示没想过。
  • float类型可以表示-232-1~232,double类型可以表示-264-1~264
  • 输出格式要求输出整型,而数是浮点型,类型转化之后输出结果为2。

有一点可以明确,我的回答都是错误的。那好吧,下面是我查看一些资料总结出来的,希望能解释清楚其中的”奥秘“。

 

IEEE754标准(以下简称”标准“)是使用最广泛的浮点数运算标准,为许多CPU与浮点运算器所采用。该标准定义了表示浮点数的格式,如下图所示:

vnsc5858威尼斯城官网 1

下面只讨论二进制浮点数的表示,分成了三个部分:

符号位、指数、尾数,它们的含义可以类比科学计数法。如:

科学计数法中: 

(102.35045)10 = 1.0235045 × 102  符号位为正,指数是2,尾数是1.0235045。

(-0.00023103)10 = -2.3103 × 10-4  符号位为负,指数是-4,尾数是2.3103。

同样在规格化二进制浮点数中:

(1001.0111010)2 = 1.001011101 × 23 符号位为正,指数是3,尾数是1.001011101。

(-0.0001010011)2 = -1.010011 × 2-4 符号位为负,指数是-4,尾数是1.010011。

由上面的实例可以知道,在二进制浮点数被规格化后,尾数的格式都是1.****,指数表示将小数点移动多少位可以实现规格化(向左指数加1,向右指数减1),因此可以正也可为负。

标准同时规定:

  • 符号位用1位表示,0表示正数,1表示负数;
  • 指数采用移码表示(原来的实际的指数值加上一个固定值得到的),这个固定值为2e-1-1(e为指数部分比特长度),之所以加上这个偏移量,是为了将负数变成非负数,这样两个指数的大小很容易就可以比较。
  • 尾数采用原码表示,正如上所说,规格化二进制浮点数最高位均为1,那么小数点前这个就没必要用一个比特位去存储,我们默认已经存在,称为”隐藏位“。

标准规定了四种浮点数的表示方式:单精确度(32位)、双精确度(64位)、延伸单精确度(43比特以上,很少使用)与延伸双精确度(79比特以上,通常以80比特实做)。C语言中float和double浮点型分别对应的是单精度和双精度浮点数,下面介绍这两种浮点数的存储格式:

vnsc5858威尼斯城官网 2

如上面两个例子,分别使用单精度和双精度表示如下:

(1001.0111010)2 = 1.001011101 × 23

单精度: 符号位0,指数位为3 127=130(10000010),尾数1.001011101隐藏最高位1之后为001011101,因此表示为:

0 10000010 00101110100000000000000

双精度:只是在指数位上加的偏移量不同,3 1023=1026(10000000010),表示为:

0 10000000010 0010111010000000000000000000000000000000000000000000

(-0.0001010011)2 = -1.010011 × 2-4

单精度:符号位1,指数位为-4 127=123(1111011),尾数1.010011 隐藏最高位1之后为010011,因此表示为:

0 01111011 01001100000000000000000

双精度:指数位为-4 1023=1019(1111111011),表示为:

0 01111111011 0100110000000000000000000000000000000000000000000000

至此,应该已经解释清楚了浮点数在计算机中的存储格式和方法了,也就等于回答了上面的第一个问题,至于第二个问题,如果理解了上面所说的,求浮点数表示的范围就应该很简单了,下表为单精度浮点数各种极值情况:

vnsc5858威尼斯城官网 3

vnsc5858威尼斯城官网,至于最后一个问题,我们写一个C语言程序进行测试:

#include <stdio.h>    int main()  {          printf("%dn", 2.5);          return 0;  }

编译运行结果如下:

[guohl@guohl]$ gcc -o test test.c -g  [guohl@guohl]$ ./test   0

运行结果和我们预期的2不一样,使用gdb调试,在main函数处插入断点,并且反汇编main函数之后得到:

(gdb) break main  Breakpoint 1 at 0x8048415: file test.c, line 5.  (gdb) run  Starting program: /home/guohl/Documents/AS/test     Breakpoint 1, main () at test.c:5  5        printf("%dn", 2.5);  (gdb) disassemble   Dump of assembler code for function main:     0x0804840c < 0>:    push   
	

编辑:计算机教程 本文来源:从IEEE754标准谈C语言浮点数据类型【vnsc5858威尼斯

关键词: