众所周知,在计算机中,所有的数据在内存中都是以二进制的形式存储的。但,尽管都是二进制存储,不同类型的数据也是以不同的规则(规定)存储的。
例如,在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
结束啦!!! 希望不太了解的小伙伴,看完之后,自己理解一下!!!大家共勉!!
点个赞再走呗~~~~~
不过最后要提醒一个东西,当一个浮点数无法转化成有限的二进制形式,那么,超出的部分将会被截取,仅存入相应的位数。如果出现这种状况就一定会造成精度的缺失,所以在使用浮点数的时候一定要将这种情况考虑进去!
不了解整型在内存中的存储规则的兄弟们,评论区留言我会写一下的!!
|