众所周知,在计算机中,所有的数据在内存中都是以二进制的形式存储的。但,尽管都是二进制存储,不同类型的数据也是以不同的规则(规定)存储的。
例如,在C语言中,整数在内存中就是以二进制补码的形式存储的,整型的运算也是用二进制补码进行运算的。(对于没有接触的兄弟们,我会再写一个整型在内存中的存储的)
那么在C语言中,浮点数(也就是 float
和 double
类型的数据)在内存中是以怎么样的规则和形式存储的呢?
让我们一起来揭露它的 ” 真面目 “ 吧!!
浮点数的二进制转换
在学习浮点数在内存中的存储规则前,我们先来学习一下,浮点数怎么从十进制转换成二进制的表示形式。
举一个小小例子:
13.25
怎么从十进制转换成二进制呢?
很简单,对于整数部分,我们采用 除2求余法
· · · · · · ·对于小数部分,我们采用 乘2求整法
上才艺
看图一目了然,根本不需要在学第二遍(好吧,其实是我不想再写第二个例子的过程了)
你学会了~吗?
浮点数在内存中的存储规则
C语言中,浮点数在内存中其实是按照IEEE 754(IEEE二进制浮点数算术标准)来存储的。
IEEE 754标准规定 任意一个浮点数 V 的二进制表示形式,可以表示为
V = (-1)^S * M * 2^e
(-1)^S 用来表示 V 的符号,S = 0时,V为正;S = 1时,V为负
对于13.25 == 1101.01;
S = 0
M 用来表示有效数字,且 1 <= M < 2
对于13.25 == 1101.01;
M = 1.10101
2^E 用来表示指数位
对于13.25 == 1101.01;
二进制可表示为 1.10101 * 2^3
即E = 3
浮点数在内存中,就是以存储S、M、E来存储的
一个浮点数存储至内存的步骤为:
1.浮点数 V 转化为二进制表示形式
2.将 V 的二进制,按照IEEE 754标准计算
3.再将计算出的S、M、E
按照模式存入内存中
浮点数实际如何存储至内存
浮点数存储至内存,到底是按照怎样的运算和排列存储的呢?
我们先来了解一下浮点数在内存中的的 存储模型
-
存储模型
上面我们说到V = (-1)^S * M * 2^e
,计算出的S、M、E就是按照如此地址顺序来存储的(一个方格为一个 bit ,从左到右,内存地址由低到高)
但是,将S、M、E存入内存还要遵循一定的运算 -
存储运算
1. 对于 S ,S 只可能等于 0 或 1,所以直接存入且仅需要1个bit位
2. 对于 M,只需要存入 M 的小数位,即 若 M = 1.10101,则只需要存入10101
因为 M 的个位数恒为 1,不需要存储(利用这种方法,可以节省 1 个 bit 的内存)
3. 对于 E,double
和float
两种类型不同,在此标准中,E 的 类型为unsigned int
无符号整数类型,但是科学计数法中,指数位可以为负数,所以标准规定 E 存入内存中必须加上一个中间值
float
:E 为 8 位,取值范围为 0 ~ 255,中间值 127
· · · · ·例:2^10 中 E = 10;保存为 float 类型时,内存中存入的是 10 + 127 = 137 = 10001001
double
:E 为 11 位,取值范围为 0 ~ 2047,中间值 1023
· · · · ·例:2^10 中 E = 10,保存为 double 类型时,存入的是 10 + 1023 = 1033 = 10000001001
浮点数的存储实例
浮点数:13.25
二进制:1101.01
IEEE 754标准:(-1)^0 * 1.10101 * 2^3
即:S = 0; M = 1.10101; E = 3
float
:
存入内存:S = 0; M = 10101; E = 3 + 127 = 130 = 10000010
二进制: 0100 0001 0101 0100 0000 0000 0000 0000
十六进制:41 54 00 00
double
:
存入内存:S = 0; M = 10101; E = 3 + 1023 = 1026 = 10000000010
二进制:0100 0000 0010 1010 1000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
十六进制:40 2a 80 00 00 00 00 00
结束啦!!!
希望不太了解的小伙伴,看完之后,自己理解一下!!!大家共勉!!
点个赞再走呗~~~~~
不过最后要提醒一个东西,当一个浮点数无法转化成有限的二进制形式,那么,超出的部分将会被截取,仅存入相应的位数。如果出现这种状况就一定会造成精度的缺失,所以在使用浮点数的时候一定要将这种情况考虑进去!
不了解整型在内存中的存储规则的兄弟们,评论区留言我会写一下的!!