[学习笔记] 二进制小数表示方法

科学计数法

科学计数法想必大家都很熟悉了,往往通过如下形式表示一个实数:
± M × R E \plusmn M \times R^E ±M×RE

其中包含几个组成部分:

  • 符号(sign):最左边的正负号;
  • 尾数(fraction)、有效位数(significand):公式中的 M M M,常常是1到10之间的小数,体现了数字的精度;
  • 基数(radix):公式中的 R R R,表示进制,科学计数法使用的就是十进制,即 R = 10 R=10 R=10
  • 指数(exponent):公式中的 E E E

比如一个十进制数字通过科学计数法表示为: 2.99792458 × 1 0 8 2.99792458 \times 10^8 2.99792458×108。而对于这种形式表示的任意一个十进制数字 d 1 . d 2 d 3 . . . d n × 1 0 E d_1.d_2d_3...d_n \times 10^E d1.d2d3...dn×10E,实际上都可以展开来计算具体的值: d 1 × 1 0 E + d 2 × 1 0 E − 1 + d 3 × 1 0 E − 2 + . . . + d n × 1 0 E − n + 1 d_1 \times 10^E + d_2 \times 10^{E-1} + d_3 \times 10^{E-2} + ... + d_n \times 10^{E-n+1} d1×10E+d2×10E1+d3×10E2+...+dn×10En+1

二进制推广

将上述概念和思想推广到二进制,也就是基数(radix) R = 2 R=2 R=2 的情况。一个实数一样可以通过类似科学计数法的形式用二进制表示,如 1.01011 × 2 2 1.01011 \times 2^2 1.01011×22。其具体值也就可以展开后换算到十进制: 1.01011 × 2 2 = 1 × 2 2 + 0 × 2 1 + 1 × 2 0 + 0 × 2 − 1 + 1 × 2 − 2 + 1 × 2 − 3 = 5.375 1.01011 \times 2^2 = 1 \times 2^2 + 0 \times 2^1 + 1 \times 2^0 + 0 \times 2^{-1} + 1 \times 2^{-2} + 1 \times 2^{-3} = 5.375 1.01011×22=1×22+0×21+1×20+0×21+1×22+1×23=5.375

计算机中的小数

既然二进制实数也可以用 ± M × R E \plusmn M \times R^E ±M×RE 的形式来表示,计算机中就可以通过分别存储该形式中的各个部分来存储一个实数。由于确定使用二进制,也就是基数 R R R 固定为2,因此不必再额外耗费空间记录。二进制中也只有0或1,故尾数部分 M M M 也就可以固定表示为 M = 1. d 1 d 2 d 3 . . . M=1.d_1d_2d_3... M=1.d1d2d3...,即 M = 1 + F M=1+F M=1+F。因此二进制实数的表示形式可以简化为: ± 1. F × 2 E \plusmn 1.F \times 2^E ±1.F×2E。其中各个部分则按如下形式存储:

符号位 ± \plusmn ±指数 E E E小数 F F F
1位double类型11位,float类型8位double类型52位,float类型23位

其中符号位只需要一位(bit)表示,0表示正、1表示负。指数部分由于有正负,故采用EXCESS表示系统,下面简单介绍一下该系统。

EXCESS表示系统

EXCESS表示系统主要目的是在不使用符号位的情况下也可以表示负数,具体思路就是以计数系统可表示的整体范围的中点作为0点,使用偏移量(Bias)来进行计数。偏移量的计算方法则为:当前值 - 中点值。如对于一个n位的二进制数,其能表示的范围为 0 → 2 n − 1 0 \to 2^{n}-1 02n1,中点即为 2 n − 1 − 1 2^{n-1}-1 2n11。中点值对应为0,小于中点的数值为负数,大于中点的值为正数。从而实现了不使用符号位也可以表示负数。

在float类型中指数部分有8位,可以表示的最大的数字为255( 2 8 − 1 2^8-1 281),中点为127( 2 7 − 1 2^7-1 271);对于double类型,指数部分有11位,可以表示的最大的数字为2047( 2 11 − 1 2^{11}-1 2111),中点为1023( 2 10 − 1 2^{10}-1 2101)。

下面以float类型为例总结十进制数值、二进制数值和对应的EXCESS系统数值(偏移量)之间的关系:

十进制二进制EXCESS表示值
2551111 1111128 (255 - 127)
2541111 1110127 (254 - 127)
1281000 00001 (128 - 127)
127 (中点值)0111 11110 (127 - 127)
1260111 1110-1 (126 - 127)
10000 0001-126 (1 - 127)
00000 0000-127 (0 - 127)

特殊情况

上述仅为普遍的表现形式,但由于已经默认小数点前固定为1,即 M = 1 + F M = 1 + F M=1+F,则通过上述方法无法表示0,同时也无法处理正负无穷等特殊情况。故定义当指数部分 E E E 均为0或均为1时为特殊情况,即普通情况下指数部分仅可使用 ( m i n + 1 ) → ( m a x − 1 ) (min + 1) \to (max - 1) (min+1)(max1) 的范围。对于float类型来说即为 00000001 ( − 126 ) → 11111110 ( 127 ) 0000 0001 (-126) \to 1111 1110 (127) 00000001(126)11111110(127)。下面简单阐述一下两种特殊情况的处理方式。

第一种特殊情况(用于处理0及接近0的值):当指数部分 E E E 全为0时,对应的值改为 m i n + 1 min + 1 min+1,对于float即为-126(-127+1)。同时小数点前变为0,即尾数部分 M = 0. F M=0.F M=0.F。此时小数部分 F F F全为0时即可表示0。

第二种特殊情况(用于处理正负无穷):当指数部分 E E E 全为1时,表示无穷(NaN)。其中符号位为0时表示正无穷、符号位为1时表示负无穷。小数部分直接忽略。

举例(float)

接下来以float类型举几个例子,首先复习一下float类型各个部分的位数:

float_bits

普通情况最大正实数

首先考虑普通情况下能表示的最大正实数,按上述的二进制表示形式,各个部分能取到的最大值分别为:
float-max

符号位 ± \plusmn ±指数 E E E小数 F F F
01111 1110111…111 (23位)

二进制下为 1.111...111 × 2 127 1.111...111 \times 2^{127} 1.111...111×2127,展开后可以计算出十进制下对应的值为 ( 1 + 2 − 1 + 2 − 2 + ⋯ + 2 − 22 + 2 − 23 ) × 2 127 = 2 128 − 2 104 ≈ 3.4028 × 1 0 38 (1 + 2^{-1} + 2^{-2} + \cdots + 2^{-22} + 2^{-23}) \times 2^{127} = 2^{128} - 2^{104} \approx 3.4028 \times 10^{38} (1+21+22++222+223)×2127=212821043.4028×1038

普通情况最小负实数

对于普通情况下能表示的最小负实数,只需要将符号位变为负号,其他部分仍然取最大值即可:
float-min

符号位 ± \plusmn ±指数 E E E小数 F F F
11111 1110111…111 (23位)

二进制下为 − 1.111...111 × 2 127 -1.111...111 \times 2^{127} 1.111...111×2127,十进制下约等于 − 3.4028 × 1 0 38 -3.4028 \times 10^{38} 3.4028×1038

普通情况最小正实数

普通情况下可以表示的最小的正实数,除符号位外各个部分能取到的最小值分别为:
float_min_positive

符号位 ± \plusmn ±指数 E E E小数 F F F
00000 0001000…000 (23位)

二进制下为 1.0 × 2 − 126 1.0 \times 2^{-126} 1.0×2126,十进制下约等于 1.1755 × 1 0 − 38 1.1755 \times 10^{-38} 1.1755×1038

特殊情况最大正实数

普通情况无法表示0或接近0的实数,因此指数部分全为0时为特殊情况,用于表示0或接近0的实数。该情况下小数部分全为0时即表示0,而小数部分全为1即为该情况下能取到的最大值:
float_max_app0

符号位 ± \plusmn ±指数 E E E小数 F F F
00000 0000 (-126)111…111 (23位)

二进制下为 0.111...111 × 2 − 126 0.111...111 \times 2^{-126} 0.111...111×2126,展开后计算出十进制下对应的值为 ( 0 + 2 − 1 + 2 − 2 + ⋯ + 2 − 22 + 2 − 23 ) × 2 − 126 = 2 − 126 − 2 − 149 (0 + 2^{-1} + 2^{-2} + \cdots + 2^{-22} + 2^{-23}) \times 2^{-126} = 2^{-126} - 2^{-149} (0+21+22++222+223)×2126=21262149。由此可见这种特殊情况下的最大值与普通情况下的最小值 2 − 126 2^{-126} 2126 相差也就只有 2 − 149 2^{-149} 2149,从而保证了不同情况下取值的相对连续。

  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值