认识浮点型

目录

前言

一、浮点数

二、IEEE规定

1、将浮点数转换为二进制形式

2、将二进制写成指数形式

3、确定S的符号,与E的值

三、存储方式

1)放入M

2)放入E

四、取出浮点数

1)E非全0、非全1

2)E为全1

3)E为全0

五、习题讲解

总结


前言

相信大家在初学C语言时,也会对单精度和双精度感到困惑。对于部分程序员,在浮点型的存储和取出是比较陌生的。了解浮点型的存储有助于提升知识储备,掌握特定误差的分析。

本文将从IEEE浮点型标准、浮点型在内存中的存储以及一道常见的题目来深入体会浮点型。

一、浮点数

浮点数与数学中的实数概念差不多,如3.14、3.14e7以及2e-8都是浮点数。所以在一个值后加上一个小数点,就成为浮点数,因此,7是整数,7.0是浮点数。

注意:

  • 浮点数有小数部分,最高位是0.xx可省略0 写成 .xx
  • 浮点数运算比整数慢
  • 浮点数通常只是实际的近似值(稍后详解),如3.0可能被存储为2.999999
  • 计算机默认浮点类型为double,在浮点数后加上 f 则为 float

常见的浮点型有float 、double、long double,精度向上增长,通常比整形的范围更大

二、IEEE规定

规定对于任意一个浮点数V,可表示为以下形式:

  •     (-1)^ S * M * 2^E
  • S:    浮点数为正取0,为负取1
  • M:任意一个浮点数可以写成二进制,将二进制写成大于1,小于2的指数形式
  • E:   指数大小

1、将浮点数转换为二进制形式

每位的权重:

.......+2^4+2^3+2^2+2^1+2^0 . 2^(-1) + 2^(-2) +2^(-3)+......

例如: 将 5.375改写为二进制形式

1)  拆分 2^2 + 2^0 + 2^(-2) + 2^(-3)

2)根据权重  101.011

2、将二进制写成指数形式

101.011的指数形式就是 1.01011*10^2

3、确定S的符号,与E的值

5.375是正数,S为0

由第二步知E为2

当浮点数转换为二进制时,总会存在无法转换的数字,比如3.33333333就无法转换

所以我们可以理解,浮点数的存储,通常只是它的近似值

三、存储方式

规定:对于32位浮点数(通常指float类型),最高位存 S   次八位存E,剩下32存放M

认识浮点型_第1张图片

认识浮点型_第2张图片

 

1)放入M

对于M,首位总是1,那么在存储时就没有必要存入首位的 1 ,如此就可以提升存储的范围

原本M可以存23位,现在就可以存24位,提升了精度。

2)放入E

对于1bit空间的无符号数的范围是0~255,但由于指数可以为负数,同时我们又不希望出现负数,

就对E的存入加上127

例如5.375

E为2,加上127,为129 129的二进制为 1000 0010 

以1000 0010 存入



四、取出浮点数

E的数值决定取出的方式

1)E非全0、非全1

E减去127(64位浮点数减去1023)

M补上首位1

按照 (-1)^S * M * 2^E 得出结果

2)E为全1

E全为1,如果再算上2的次方,那就是一个特别大的数字

对于这种情况,编译器会判断为(-1)^S*无穷大的数字

3)E为全0

E为全零,再减去127,就会是一个非常小的数

规定就不再往M首位补上1,而是会解读为一个非常接近0的数字

五、习题讲解

int main()
{
	int n = 1;
	float* p1 = (float*)&n;
	printf("p1的值%f\n", *p1);

	*p1 = 1.0;
	printf("n的值是:%d\n", n);
	printf("*p1的值:%f\n", *p1);


	return 0;
}

这道题,首先创建一个int 型变量 n ,

接着将n放进一个浮点型的指针,然后用浮点型的方式打印出n的值

通过浮点型指针修改n的值,分别用整形,浮点型,打印出 n 

认识浮点型_第3张图片

题解:

n: 1的二进制存储 00000000 00000000 00000000 00000001

在第一次打印,以浮点型取出,则编译器则认为n本就是浮点型存储,所以取出以SME的规定的方式

第一位是S 0 代表正数,紧着这8位代表E,E的取出分3种(不为全1\0,全0,全1)。

而这里是全0,代表一个非常接近0的数,则解读成0

通过指针存放浮点型

1.0 S为0,M为1.0,E为0,存放时,减去127 为  -127  ;

-127  的二进制为11111111(首位是符号位)

存入  0 11111111 000000000000000000000000

第二个打印,以整形的方式打印,则编译器认为n以整形存放 将存入的值以二进制方式转换出就是

1065353216   

第三个打印

以浮点型的方式取出,编译器则认为数据就是以浮点型存入,而数据就是浮点型存入,取出就是1.000000


总结

这里再次熟悉浮点型的存储与取出,了解了S E M的规则;

这里再深入理解单精度和双精度,

单精度是32位存储,E存8位,M存23位

双精度是64位存储,E存11位,M存52位

因此双精度和范围远大于单精度。

代码++

offer++

你可能感兴趣的:(C语言知识,面试,c语言,经验分享)