【计组笔记-4】定点数,浮点数,IEEE 754标准,与常见数据类型
1. 定点数与浮点数介绍
定点数,就是小数点固定的数,即在一个二进制数中,固定一部分代表整数,一部分代表小数。此外,小数点是隐式存在的,并不会有哪个二进制位专门空出来表示小数点。
浮点数,顾名思义,就是小数点不固定的数。
那么问题来了,定点数的点定在哪里,又如何记录浮点数小数点的位置呢?(毕竟小数点隐式存在)可以想象,如果没有一套统一的规则来指导定点数与浮点数的实际实现方式,各个平台间将很难正确解析信息。
2. IEEE 754标准
引用百度百科里的一句话:
IEEE 754规定了四种表示浮点数值的方式:单精确度(32位)、双精确度(64位)、延伸单精确度(43比特以上,很少使用)与延伸双精确度(79比特以上,通常以80位实现)。
在c++中,float为单精度类型,double为双精度,此外我搜索了一下,似乎并没有提供后面两种类型,但c++提供了long double(与754里的延伸双精度不同,c++里的是128位的)
3. 浮点数类型
3.1 float
3.1.1 float储存思路
float由4个字节32位组成,其中,最高位为符号位(1负0正),后面跟着8位是指数位,剩下的23位均为数值位。
分析一下这样储存的含义:在十进制下,用科学计数法表示一个数值,可以用诸如1.2345x1015这样的方式,其中,15就是指数,而1015次方意味着,需要将小数点右移15位。也可以说,1015指明了小数点的位置。
将1.2345理解为基础数值,如果它的小数点位置是事先定义好,不会变动的,则一定可以通过将基础数值与10的不同次方相乘,来固定表示一个数值。
将10进制修改为2进制,即为float的储存思路,符号位表示正负,指数位用来储存小数点移动的位数(即指数),而剩余23位数值位用来储存“基础数值”,通过这样的方法,就可以在一串二进制位中同时储存正负信息,小数点的位置信息,以及数值本身的信息。
3.1.2 float中的指数位
指数位的部分是有符号定点整数,且用移码的形式储存,移码在笔记-6里有详细分析过了,这里不多写了,移码的优点是可以很好的对比有符号整数的大小,进而加速浮点数的计算。
简单来说,在整数相加的过程中,只要直接计算即可,但是浮点数相加的过程中,有一个对比阶数的过程,用10进制举例,3.2x1012+1.5x1010=3.2x1012+0.15x1012=(3.2+0.15)x1012,最后的阶数是12,即12和10中的较大值,可见,在浮点数计算过程中,有一个阶数对比的步骤。
————————————————
原文链接:https://blog.csdn.net/qq_41562387/article/details/115834796
移码的计算方法是真值+偏置值,不同的设计思路,阶码位数,对应的偏置值也不一样,例如,在754标准中,n位阶码的偏置值是2n-1-1,对应移码的0是从真值的最小值的上一位开始的,即最小值+1,它主要是把真值的最小值和最小值-1这俩状态单独挑出来作其他用途了,因此才这样设计偏置值。(具体偏置值和移码的概念可以看【计组笔记-6】详细分析原码,反码,补码,以及移码),这里只要知道移码是为了方便阶数比大小就行了。
上面说过,754标准中,移码的0是从-2n-1+1开始的,因此偏置值是-2n-1+1的绝对值,即2n-1-1,在这种情况下,-2n-1的移码全为1,-2n-1+1的移码全为0,在754标准的浮点数中,指数位全0和全1被设定了特殊用途,下面具体分析一下。
3.1.3 指数位的特殊状态
理论上讲,8位指数位+23位数值位(定点小数)的最小绝对值应为2-23x2-128=2-151,然而,由于754规定数值位的最高位隐式为1(下面有分析数值位),且最小阶数为-126,因此,在这种情况下,最小绝对值实际为1x2-126,显然能够表示的范围比理论上要小了很多。
由于最小绝对值是在最高位隐式为1的限制下才缩小了范围,而最大绝对值即使限制了最高位隐式为1,也并不会影响它的范围(毕竟最大值本来最高位就是1),因此,似乎并不需要考虑扩展最大值的范围,然而,754规则中,对无穷值与非法值也做了考虑。
综上所述,由于754规则考虑到扩充最小绝对值,以及表示无穷与非法值,因此它设置了两个特殊状态,下面分别讨论一下。
当指数位全为0,且数值位不全为0时,认为数值位的最高位为0,且阶数为-(2n-1-2),-2是去掉指数位的两个特殊状态,正负由符号位决定。
当指数位全为0,且数值位也全为0时,认为储存的数值为0,正负由符号位决定(可见,浮点数是有分+0和-0的,但是像int这样的类型是没有-0的)。
当指数位全为1,且数值位不全为0时,认为储存的是非法值,即NaN(not a number的缩写)。
当指数位全为1,且数值位也全为0时,认为储存的是无穷值,正负由符号位决定。
可见,浮点数可以表达更多的提示性信息,而定点整数如int类型,则只具有储存数据的功能。
3.1.3 float中的数值位
数值位的部分是最高位隐式为1的定点小数,且用原码的形式储存,就像10进制的科学计数法一样,数值位的最高位需要是有效值,而2进制的有效值一定是1,因此,这个1隐式存在(也就是不存,这样可以多存一位,扩大点表示范围),例如,如果一个浮点数的数值位储存的是011,则在计算真值时,数值位的实际数值应该是1011。此外,小数点隐式存在于数值位的最开头,也就是,如果数值位存的是011,则真实值为1.011。
整个浮点数储存的真实值,就是数值位真实值,再乘以2的若干次(由指数位决定),并且正负由符号位决定。
3.2 float之外的
其余的如double,long double之类的,如果是基于754标准,则原理上跟float一样,只是指数位和数值位的位数有点区别,其他的都是一样的,也是有俩特殊状态等等,不多赘述。
已知的是java,c,c++用的都是754标准,是否有哪种语言或哪个浮点型没有用754,可以自己查阅了解下吧,写在这里权当提醒。
4. 定点数类型
一般直接给出的类型都是定点整数。
在给出的类型中,一般而言,int是32位二进制有符号数,且用补码储存,其余的诸如short,long int,long long,或者一些语言支持的特殊类型比如64位int等等,只要不加unsigned修饰,那就是有符号补码,只是位数有所不同而已,并且,整数对溢出的处理也比较简单粗暴,就是截断,不像浮点数还有无穷和NaN。
5. 总结&补充
贴两个相关笔记,作为本篇的补充,如下: