大家好,我是LoveHutao,我们在位操作符中已经讲过了整形(int)在内存中的存储是以二进制补码的形式来储存的,今天我们来了解一下浮点型在内存中的存储方式吧!
一.回顾浮点型
浮点型包括双浮点型(double),和浮点型(float),这两个浮点型的区别在于的精度不同,为什么会产生精度问题呢?当我们了解了浮点型的存储方式后,就一目了然了。
二.浮点型在内存中的存储
1)浮点数的储存方式
浮点型在内存中的存储不是像整形那样直接存储的,而是用一种二进制的科学计数法来表示的,具体的数学表达式为 V = (-1)^s * M * 2^E,我们知道float所占用的内存为4个字节,其存储方式具体分为三个部分,第一部分是符号位占1bit,用来判断它的正负性,第二部分是指数位占8bit,用来判断它的次数,第三部分是有效数字(小数点后),占23bit,而double类型只是相当于float的拓宽,话是这么说,那么到底是如何存储的呢?接下来我会将三部分分开来讲述。
1.第一部分(符号位)
浮点型的符号位和整型相同同样是0代表正数,1代表负数。
2.第二部分(指数位)
这里的指数位并不是我们常用的10^n,而是二进制中的指数位,也就是2^n,前面也说过,浮点型在内存中的存储是以二进制的科学记数法来储存的,既然是科学记数法,那n必然是有正有负的因此我们想要指数位的存储中也包含负数,怎么办呢?如果还想之前一样以第一位作为符号位未免有些麻烦,因此计算机中直接将指数位的值-127得到我们需要的指数,例如:2^-1在指数位中的存储就是01111110。
3.第三部分(有效数字)
在二进制的科学计数法中,由于二进制中每一位只有0或1,因此计算机就可以默认二进制中第一位为1,就可以节省一位数字来存储更多的数字以获取更高的精确度,别看只有一位,但是当它是在22位的基础上加一位时,我们可以多表示2^22个有效数字,这能极大地缓解内存压力!这也就是为什么二进制中有效数字存储的是小数点后的有效数字,因为计算器会自动在前面补上1.0。
4.double类型
double类型的实质和float类型没有任何区别,但是double类型的指数位有11bit,有效数字部分有52bit,这也是为什么double类型要比float精度更高的原因,这里我就不单独画图演示了。
三.浮点数的误差
我们在输出浮点数的时候有时会遇到输出的结果和它本应该的结果差一点点,这就是由浮点数的误差造成的,例如我想要打印20.7这个数字:
int main()
{
float a = 20.7;
printf("%f",a);
return 0;
}
这是因为浮点数在函数中的储存方式决定的,例如此处的20.7,由于(-1)^0*2^n*M在浮点数最小范围内找不到一样的值,因此就输出了能够找到的与之最相近的值,(其实浮点数就相当于2的最小次幂一只加到最大次幂的和),所以现在我们应该能够理解为什么浮点型会存在误差了吧!
好的,我是LoveHutao,感谢大家的观看!