PC_浮点数表示/定点数和浮点数比较/溢出/C语言中的浮点数类型
浮点数
-
根据小数点的位置是否固定,分为定点数和浮点数
-
定点数采用不同机器数编码(原码/补码/移码)的情况
-
定点数
- 定点补码整数表示整数
-
浮点数
- 浮点数不再使用补码来表示,而是用原码和移码组合表示
- 定点原码小数表示浮点数的尾数(定点小数)
- 移码表示浮点数阶码部分(移码整数)
- 浮点数不再使用补码来表示,而是用原码和移码组合表示
-
参考IEEE 754标准
-
ref
浮点数表示
- 浮点数表示法是指以适当的形式将比例因子表示在数据中,让小数点的位置根据需要而浮动。
- 这样,在位数有限的情况下,既
扩大了数的表示范围
,又保持
了数的有效精度
。- 例如,用定点数表示电子的质量或太阳的质量是非常不方便的。
- 使用浮点是可以较好表示
浮点数形式分析
-
一个浮点数可以分为两大部分:阶数;尾数
-
阶数:{(阶符),(阶码数值)};
- 阶符
- 阶码
-
尾数:{(数符).(数码数值)}
- 数符
- 数码
-
计算机中,基数是默认值为2,不用写出来
-
书面形式的一般浮点数(真值)
-
这个部分是以真值的形式讨论(真值的二进制形式)
- 某些语境下,是以真值的机器码表示的(比如补码/原码/移码)
- 不同机器编码下得到的规律不一样,不要混淆了,但真值形式是根本
-
对于r进制的浮点数,可以表示为:
-
N = S × r j N=S\times{r^j} N=S×rj
-
其
中
其中
其中
-
S
是
尾
数
S是尾数
S是尾数(可正可负)
- 可以采用定点原码小数表示
-
j
j
j为阶码(指数)(也就是基数r的指数)(可正可负)
- 可以采用移码整数
- r r r是基,在计算机中,通常r=2,即二进制(也可以去2的其他幂,比如4,8,…)
-
S
是
尾
数
S是尾数
S是尾数(可正可负)
-
其
中
其中
其中
-
-
在计算机中,为了提高数据的精度,以及便于比较
- 规定浮点数的尾数用纯小数的形式
- S ∈ [ 0 , 1 ) S\in[0,1) S∈[0,1)
- 比 如 1 表 示 为 0.1 × 10 比如1表示为0.1\times{10} 比如1表示为0.1×10
- 比如
a
=
0.11
×
2
10
1
2
a=0.11\times{2^{101_2}}
a=0.11×21012
- b = 0.011 × 2 10 1 2 b=0.011\times{2^{101_2}} b=0.011×21012
- 可以看到,表示相同值的两个数a,b的尾数部分0.11和0.011占用了不同位数的小数位
- 为进一步提高精度(在有限的机器字长位数下),一般采用规格化数
- 将在规格化数部分讨论
- 规定浮点数的尾数用纯小数的形式
小数:纯小数和带小数(混小数)
- 小数,是实数的一种特殊的表现形式。
- 整数部分是零的小数叫做纯小数(pure decimal),
- 如0.3,0.48,0.999等。
- 整数部分不为零的小数叫做带小数(mixed decimal)
- reference link
🎈二进制规格化浮点数
-
为了进一步规范浮点数(保证尽可能高的精度)提出规格化数(浮点数)
- 最高位是1的浮点数就是规格话数,例如
- a = 0.11 × 2 10 1 2 a=0.11\times{2^{101_2}} a=0.11×21012,而b就不是
- c = 101.11 × 2 10 1 2 c=101.11\times{2^{101_2}} c=101.11×21012这个也不是,因为它位数是纯小数的条件的都不满足
- 最高位是1的浮点数就是规格话数,例如
-
对于基数不同的浮点数,其规格化数的标准有所不同,规格化的过程也有所不同
计算机中的二进制浮点数形式
- 本节依然是从真值的二进制形式讨论
非标准形式讨论浮点数
-
通常,机器中的浮点数形如:
-
F = j f j 1 ⋯ j m ⏟ 阶 码 ( 数 值 部 分 ) S f S 1 ⋯ S n ⏟ 尾 数 的 数 值 部 分 F=j_f\underbrace{j_1\cdots{j_m}}_{阶码(数值部分)}S_f\underbrace{S_1\cdots{S_n}}_{尾数的数值部分} F=jf阶码(数值部分) j1⋯jmSf尾数的数值部分 S1⋯Sn
-
该形式可以看做两大部分:
-
阶 码 ( 也 叫 ( 基 的 ) 指 数 ) j = j f j 1 ⋯ j m 阶码(也叫(基的)指数)j=j_fj_1\cdots{j_m} 阶码(也叫(基的)指数)j=jfj1⋯jm
- j f 是 阶 符 j_f是阶符 jf是阶符
- j是整数,反映了浮点数的表示范围和小数点的位置
-
尾数 S = S f S 1 ⋯ S n S=S_fS_1\cdots{S_n} S=SfS1⋯Sn
- S f S_f Sf是数符
- S是纯小数,反映了浮点数的精度,位数的符号 S f S_f Sf代表了浮点数的正负
-
小数点:
- 尾数是纯小数,其小数点位于 S j S_j Sj和 S 1 S_1 S1之间
- 阶码j是定点整数,也有自己的小数点(位于
j
m
j_m
jm和
S
f
S_f
Sf之间)
- 但是实际决定F的取值范围的,是阶码整体j
-
-
-
回顾书面形式的浮点数: F = S × r j F=S\times{r^j} F=S×rj
- S就是尾数
- j就是阶码
- 基数r被默认为2
-
IEEE标准中的结构
- 和非标准结构大致类似,但是数符 S f S_f Sf被提前了到浮点数结构的第一部分(参看文末部分)
🎈🎈🎈浮点数的表示范围(非规格化时)
- 设浮点数
阶码的数值位取m位
,尾数的数值位取n位
,当浮点数为非规格化数时,它在数轴上的表示范围:
- 浮 点 数 = 阶 数 × 尾 数 浮点数=阶数\times 尾数 浮点数=阶数×尾数
n位数值位的小数和整数最值
-
下面的讨论是基于真值(与具体机器数编码相独立)
-
纯小数:
-
∣ p ∣ ∈ ( 0 , 1 ) ∣ p ∣ ∈ [ 2 − n , 1 − 2 − n ] − ∣ p ∣ ∈ [ 2 − n − 1 , − 2 − n ] 2 − n = 0. 0 ⋯ 01 ⏟ n − 1 个 0 , 末 尾 1 1 − 2 − n = ( 0. 1 ⋯ 11 ⏟ n 个 1 ) 2 = ∑ i = 1 n 2 − i |p|\in(0,1) \\ |p|\in[2^{-n},1-2^{-n}] \\-|p|\in[2^{-n}-1,-2^{-n}] \\\\ \\2^{-n}=0.\underbrace{0\cdots{01}}_{n-1个0,末尾1} \\1-2^{-n}=(0.\underbrace{1\cdots{11}}_{n个1})_2=\sum\limits_{i=1}^{n}2^{-i} ∣p∣∈(0,1)∣p∣∈[2−n,1−2−n]−∣p∣∈[2−n−1,−2−n]2−n=0.n−1个0,末尾1 0⋯011−2−n=(0.n个1 1⋯11)2=i=1∑n2−i
-
纯小数对应于浮点数的尾数(的数值位部分)
-
-
整数:
-
∣ z ∣ = 0 , 1 , 2 , ⋯ , 2 n − 1 − ∣ z ∣ = 1 − 2 n , ⋯ 0 |z|=0,1,2,\cdots,2^{n}-1 \\ -|z|=1-2^{n},\cdots{0} ∣z∣=0,1,2,⋯,2n−1−∣z∣=1−2n,⋯0
-
对应于浮点数阶码(数值位部分)
-
-
设浮点数 F = j f j 1 ⋯ j m S f S 1 ⋯ S n F=j_fj_1\cdots{j_m}S_fS_1\cdots{Sn} F=jfj1⋯jmSfS1⋯Sn
-
即,阶码数值位部分有m位,尾数数值部分n位
-
浮点数的取值范围具有对称性
-
下面仅对正数的一侧做讨论
- 最小浮点数(浮点数最小绝对值):
-
注意到,浮点数的正负性是由尾数的数符位 S f S_f Sf决定的
- 阶码总是正数(尽管阶符可以是负的
- 指数函数( 2 j 2^{j} 2j总是有大于0的函数值, 2 x 2^x 2x是个递增函数,
- 所以,当j取得最小值 2 − 1 ⋯ 11 = 2 − ( 2 m − 1 ) 2^{-1\cdots{11}}=2^{-(2^{m}-1)} 2−1⋯11=2−(2m−1)
- 同 时 尾 数 S 取 到 最 小 值 0.0 ⋯ 01 = 2 − n 同时尾数S取到最小值0.0\cdots{01}=2^{-n} 同时尾数S取到最小值0.0⋯01=2−n
- 阶码总是正数(尽管阶符可以是负的
-
最小阶码( 2 − ( 2 m − 1 ) 2^{-(2^m-1)} 2−(2m−1)乘以最小尾数:(最接近0的正浮点数数)
- J M i n ∣ S ∣ M i n = 2 − ( 2 m − 1 ) 2 − n J_{Min}|S|_{Min}=2^{-(2^{m}-1)}2^{-n} JMin∣S∣Min=2−(2m−1)2−n
-
最 大 阶 码 ( 2 ( + ( 2 m − 1 ) ) ) 乘 以 最 大 尾 数 ( 2 − n − 1 ) 最大阶码(2^{(+(2^m-1))})乘以最大尾数(2^{-n}-1) 最大阶码(2(+(2m−1)))乘以最大尾数(2−n−1)
- J M a x ∣ S ∣ M a x = 2 ( 2 m − 1 ) ( 2 − n − 1 ) J_{Max}|S|_{Max}=2^{(2^{m-1})}(2^{-n}-1) JMax∣S∣Max=2(2m−1)(2−n−1)
-
- 最小浮点数(浮点数最小绝对值):
-
小结:
- 以上就是正半轴的情况,负半轴取符号得到对称的边界值
- 最大负浮点数:(最接近0的负浮点数)
- − J M i n ∣ S ∣ M i n = − ( 2 − ( 2 m − 1 ) 2 − n ) -J_{Min}|S|_{Min}=-(2^{-(2^{m}-1)}2^{-n}) −JMin∣S∣Min=−(2−(2m−1)2−n)
- 最小负浮点数:(最远离0的负浮点数)
- − J M a x ∣ S ∣ M a x = − ( 2 ( 2 m − 1 ) ( 2 − n − 1 ) ) -J_{Max}|S|_{Max}=-(2^{(2^{m-1})}(2^{-n}-1)) −JMax∣S∣Max=−(2(2m−1)(2−n−1))
-
特点:
-
观察上述最值,发现阶码的数值部分绝对值是最大的m位二进制数
-
🎈以下的0/1串都是真值的二进制形式
-
2 − 1 ⋯ 11 × 0.0 ⋯ 01 2 + 1 ⋯ 11 × 0.1 ⋯ 01 − 2 − 1 ⋯ 11 × 0.0 ⋯ 01 − 2 + 1 ⋯ 11 × 0.1 ⋯ 01 2^{-1\cdots{11}}\times0.0\cdots{01} \\ 2^{+1\cdots{11}}\times0.1\cdots{01} \\ -2^{-1\cdots{11}}\times0.0\cdots{01} \\ -2^{+1\cdots{11}}\times0.1\cdots{01} 2−1⋯11×0.0⋯012+1⋯11×0.1⋯01−2−1⋯11×0.0⋯01−2+1⋯11×0.1⋯01
-
-
-
🎈浮点数表示范围和溢出
-
判断浮点数溢出,是通过比较阶码来进行
-
上溢:
- 这个好理解,当浮点数的阶码大于最大阶码时,就是发生上溢,这种情况下机器停止运行,进行中断溢出处理
- 正上溢和负上溢,绝对值都是向无穷大方向发展而发生的
-
下溢:
- 当浮点数阶码小于最小阶码时,称为下溢
- 正下溢和负下溢的绝对值都是向0靠近而发生的
- 注意,浮点数可以取到0
- 但是,由于精度的限制(尾数位数有限),很接近0但不等于0的数是表示不了的(存在一个类似于盲区的区域)
- 即,在值落在0的邻域时,可能发生下溢
- 此时的数绝对值十分小,通常的,将尾数各位强制置为0,按照机器零处理
🎈规格化数
🎈🎃定点数vs浮点数
- 当浮点机和定点机中的位数相同
- 范围:浮点数的表示范围比定点数大得多
- 定点数和浮点数都可以表示
- 整数
- 小数
- 在定点机中,由于小数点位置固定不变,当机器处理的数不是纯小数或者纯整数的时候,需要乘以一个比例因子,否则会产生溢出
- 采用定点小数的机器称为定点机
- 数值部分的位数n决定了定点机中数的表示范围
- 如果机器数采用原码:
- 小数定点机中的表示范围是 − ( 1 − 2 − n ) ∼ 1 − 2 − n -(1-2^{-n})\sim{1-2^{-n}} −(1−2−n)∼1−2−n(对称)
- 整数定点机中数的表示范围: − ( 2 n − 1 ) ∼ 2 n − 1 -(2^n-1)\sim{2^n-1} −(2n−1)∼2n−1
- 定点数和浮点数都可以表示
- 精度:当浮点数是规格化数时,其相对进度也比定点数高得多
- 这要分情况:比如对于x=0.1001011 101010…,y=0.00000000010110…
- 对于两台相同字长(8位)的定点机A和浮点机B:
- x用A表示精度更高
- 因为x已经是规格化数,定点机的所有bit都可以用来表示尾数的各个位数,可以达到最高精度
- y用B表示精度更高
- 前提是y要进行规格化,这样可以将有效位表示到更后面.
- 这要分情况:比如对于x=0.1001011 101010…,y=0.00000000010110…
- 运算效率:定点数运算比较快
- 浮点数运算要分为阶码部分和位数部分的运算
- 而且运算结果都要规格化,(浮点数的运算步骤比定点数多)
- 溢出判断:
- 浮点数的溢出判断是对规格化数的阶码进行判断
- 定点数是对数值本身进行判断
- 比如,小数定点机中的数,其绝对值如果大于1,就是溢出
- 为了避免溢出,处理非纯小数前,需要选择比例因子,比较麻烦
- 原因是定点数的小数点被规定在符号位之后,且不可移动
- 浮点数的表示范围大,仅当上溢才会停止运算,一般不考虑比例因子的选择
- 比如,小数定点机中的数,其绝对值如果大于1,就是溢出
- 定点机可以通过软件实现浮点运算或者外加浮点扩展硬件
- 范围:浮点数的表示范围比定点数大得多
IEEE 754标准的浮点数格式
S f E S 1 ∼ n 数 符 阶 码 部 分 ( 移 码 整 数 ) 尾 数 数 值 位 ( 用 定 点 原 码 ) S f ( 数 符 ) 阶码(含阶符) 尾数 \\ \begin{array}{|l|l|l|} \hline S_f & E & S_{1\sim{n}} \\ \hline 数符&阶码部分(移码整数)&尾数数值位(用定点原码) \\\hline \end{array} \\ \begin{array}{|l|c|c|} \hline S_f(数符) & \text { 阶码(含阶符) } & \text { 尾数 } \\ \hline \end{array} Sf数符E阶码部分(移码整数)S1∼n尾数数值位(用定点原码)Sf(数符) 阶码(含阶符) 尾数
-
符号位 S 阶码 尾数 总位数 短实数 1 8 23 32 长实数 1 11 52 64 临时实数 1 15 64 80 \begin{array}{lcccc} & \text { 符号位 } S & \text { 阶码 } & \text { 尾数 } & \text { 总位数 } \\ \text { 短实数 } & 1 & 8 & 23 & 32 \\ \text { 长实数 } & 1 & 11 & 52 & 64 \\ \text { 临时实数 } & 1 & 15 & 64 & 80 \end{array} 短实数 长实数 临时实数 符号位 S111 阶码 81115 尾数 235264 总位数 326480
-
其中,S为数符,它表示浮点数的正负,但与其有效位(尾数)是分开的。
-
阶码用移码表示,阶码的真值都被加上一个常数(偏移量),
- 如短实数,长实数和临时实数的偏移量用十六进制数表示分别为7FH,3FFH和3FFFH。
- 尾数部分
通常
都是规格化表示,即非“O”的有效位最高位总是“1”,但在IEEE标准中,有效位呈如下形式。
1▲ffff……-fff
其中▲表示假想的二进制小数点。 - 在实际表示中,对短实数和长实数,
这个整数位的1省略
,称隐藏位
; - 对于临时实数不采用隐藏位方案
表格
Name | Common name | Base | Significand bits[b] or digits | Decimal digits | Exponent bits | Decimal E max | Exponent bias[14] | E min | E max | Notes |
---|---|---|---|---|---|---|---|---|---|---|
binary16 | Half precision | 2 | 11 | 3.31 | 5 | 4.51 | 2 4 − 1 = 15 2^4−1 = 15 24−1=15 | −14 | +15 | not basic |
binary32 | Single precision | 2 | 24 | 7.22 | 8 | 38.23 | 2 7 − 1 = 127 2^7−1 = 127 27−1=127 | −126 | +127 | |
binary64 | Double precision | 2 | 53 | 15.95 | 11 | 307.95 | 2 10 2^{10} 210−1 = 1023 | −1022 | +1023 | |
binary128 | Quadruple precision | 2 | 113 | 34.02 | 15 | 4931.77 | 2 14 2^{14} 214−1 = 16383 | −16382 | +16383 | |
binary256 | Octuple precision | 2 | 237 | 71.34 | 19 | 78913.2 | 2 18 − 1 = 262143 2^{18}−1 = 262143 218−1=262143 | −262142 | +262143 | not basic |
decimal32 | 10 | 7 | 7 | 7.58 | 96 | 101 | −95 | +96 | not basic | |
decimal64 | 10 | 16 | 16 | 9.58 | 384 | 398 | −383 | +384 | ||
decimal128 | 10 | 34 | 34 | 13.58 | 6144 | 6176 | −6143 | +6144 |
例
- 下表列出了十进制数178.125的实数表示。
-
实数表示 数值 原式十进制数 178.125 二进制数 10110010.001 二进制浮点数表示 1.0110010001 × 2 111 1.0110010001\times{2^{111}} 1.0110010001×2111 -
短实数表示
-
符号 移码的阶码 有效位 0 00000111+01111111=10000110 01100100010000000000000
-
从真值算得其IEEE754表示形式
- 设真值为x
- 例 如 x = + 178.125 例如x=+178.125 例如x=+178.125,采用32为IEEE754规格的32位规格(8位用来保存阶码)
-
真
值
的
二
进
制
形
式
=
+
10110010.001
真值的二进制形式=+10110010.001
真值的二进制形式=+10110010.001
- 按原码规格化该浮点数:
- x = 0.10110010001 × 2 + 8 x=0.10110010001\times{2^{+8}} x=0.10110010001×2+8
-
x
=
1.0110010001
×
2
+
7
x=1.0110010001\times{2^{+7}}
x=1.0110010001×2+7
- 可以将这种形式称为IEEE754规格化
- 这种形式的规格化数落在[1,2)区间内
- 即,开头总是1,这样可以不用可以用个位(bit)来存储这个1,从而可以而外的多表示移位小数(提高一点精度)
- 其中:
- 阶 码 E = + 7 阶码E=+7 阶码E=+7
-
尾
数
数
值
位
M
=
.
0110010001
尾数数值位M=.0110010001
尾数数值位M=.0110010001
- 由于IEEE的隐藏1处理,因此尾数最终从 1.0110010001 变 为 . 0110010001 1.0110010001变为.0110010001 1.0110010001变为.0110010001
- 小数点还是先出来,但是机器中不保存小数点
- 0 ⩽ M < 1 0 \leqslant M<1 0⩽M<1
- 按原码规格化该浮点数:
- 基于IEEE规格化形式的二进制串,进行阶码和位数的机器数化编码:
- 符号位:整数用0表示,负数用1表示,本例为正数,用0编码( S f = 0 S_f=0 Sf=0)
- 用移码来编码基数的指数(阶码), E = O ( + 7 ) = 2 7 + 7 = 1000000 0 2 + 11 1 2 = 10000111 E=O(+7)=2^7+7=10000000_2+111_2=10000111 E=O(+7)=27+7=100000002+1112=10000111
- 用定点小数原码来编码IEEE规格化尾数数值部分, M = T ( M ) = 0110010001 M=T(M)=0110010001 M=T(M)=0110010001
从IEEE754表示形式计算其表示的真值
-
设B=偏置值:
- B i = { 127 , i=1,single precision,8bit阶码 1023 , i=2,double precision,11bit阶码 x = ( − 1 ) S f × 1. M × 2 E − B i ∣ x ∣ = 1. M × 2 E − B i 其 中 , 1. M = 1 + M , ( M ∈ [ 0 , 1 ) ) 注 意 这 里 的 1. M 的 1 不 是 符 号 位 ( 符 号 位 是 用 单 独 的 数 符 S f 表 示 的 ) I E E E 的 规 格 化 尾 数 的 绝 对 值 ( 换 原 被 隐 藏 的 1 ) , 也 就 是 ( 1. M ) 取 值 落 在 [ 1 , 2 ) 的 范 围 内 1. M 是 非 负 的 ( 或 者 是 无 符 号 的 ) , 它 的 符 号 位 在 头 部 ( S f ) B_i=\begin{cases} 127,&\text{i=1,single precision,8bit阶码} \\1023,&\text{i=2,double precision,11bit阶码} \end{cases} \\ \begin{aligned} \\x&=(-1)^{S_f}\times{1.M}\times{2^{E-B_i}} \\|x|&=1.M\times{2^{E-B_i}} \end{aligned} \\其中,1.M=1+M,(M\in[0,1)) \\注意这里的1.M的1不是符号位(符号位是用单独的数符S_f表示的) \\IEEE的规格化尾数的绝对值(换原被隐藏的1),也就是(1.M)取值落在[1,2)的范围内 \\1.M是非负的(或者是无符号的),它的符号位在头部(S_f) Bi={127,1023,i=1,single precision,8bit阶码i=2,double precision,11bit阶码x∣x∣=(−1)Sf×1.M×2E−Bi=1.M×2E−Bi其中,1.M=1+M,(M∈[0,1))注意这里的1.M的1不是符号位(符号位是用单独的数符Sf表示的)IEEE的规格化尾数的绝对值(换原被隐藏的1),也就是(1.M)取值落在[1,2)的范围内1.M是非负的(或者是无符号的),它的符号位在头部(Sf)
🎈IEEE 754浮点数的表示范围
IEEE浮点数的精度和范围
一旦浮点数的位数确定后,合理分配阶码
和尾数
的位数
,直接影响浮点数的表示范围和精度
。
- 通常对于短实数(总位数为32位),阶码取8位(含阶符1位) ,尾数取24位(含数符1位);
- 对于长实数(总位数为64位),阶码取11位(含阶符1位) ,尾数取53位(含数符1位);
- 对于临时实数(总位数为80位),阶码取15位(含阶符1位) ,尾数取65位(含数符1位)。
阶码全为0/1的情况
- 全0阶码同时全0尾数,表示
±
0
\pm0
±0,符号取决于数符
S
f
S_f
Sf
- 通常它们等效
- 全1阶码全0尾数,表示
±
∞
\pm\infin
±∞
- 引入无穷大是为了使得计算过程中出现异常,依然能够进行下去
阶码不为全0也不为全1的情况
短浮点数
-
1+8+23
-
最小绝对值
- E = 1 , M = 0 ; 对 应 的 真 值 m i n = 1. M × 2 E − B 1 = 1.0 × 2 1 − 127 = 1.0 × 2 − 126 E=1,M=0; \\对应的真值min=1.M\times{2^{E-B_1}}=1.0\times2^{1-127}=1.0\times{2^{-126}} E=1,M=0;对应的真值min=1.M×2E−B1=1.0×21−127=1.0×2−126
-
最大绝对值:
- E = ( 2 8 − 1 ) − 1 = 1 ⋯ 11 − 1 = 1 ⋯ 10 = 254 M = 1 − 2 − 23 对 应 的 真 值 为 : m a x = 1. M × 2 E − B 1 = ( 2 − 2 − 23 ) × 2 254 − 127 = ( 2 − 2 − 23 ) × 2 127 \\ \begin{aligned} E&=(2^8-1)-1 \\&=1\cdots{11}-1 \\&=1\cdots{10}=254 \\M&=1-2^{-23} \end{aligned} \\对应的真值为: max=1.M\times{2^{E-B_1}} =(2-2^{-23})\times2^{254-127} ={(2-2^{-23})}\times2^{127} EM=(28−1)−1=1⋯11−1=1⋯10=254=1−2−23对应的真值为:max=1.M×2E−B1=(2−2−23)×2254−127=(2−2−23)×2127
-
长浮点数
-
1+11+52
-
最小绝对值
- E = 1 , M = 0 ; 对 应 的 真 值 m i n = 1. M × 2 E − B 2 = 1.0 × 2 1 − 1023 = 1.0 × 2 − 1022 E=1,M=0; \\对应的真值min=1.M\times{2^{E-B_2}}=1.0\times2^{1-1023}=1.0\times{2^{-1022}} E=1,M=0;对应的真值min=1.M×2E−B2=1.0×21−1023=1.0×2−1022
-
最大绝对值:
- E = ( 2 11 − 1 ) − 1 = 1 ⋯ 10 = 2046 M = 1 − 2 − 52 对 应 的 真 值 为 : m a x = 1. M × 2 E − B 2 = ( 2 − 2 − 52 ) × 2 2046 − 1023 = ( 2 − 2 − 52 ) × 2 1023 \\ \begin{aligned} E&=(2^{11}-1)-1 \\&=1\cdots{10}=2046 \\M&=1-2^{-52} \end{aligned} \\对应的真值为: max=1.M\times{2^{E-B_2}} =(2-2^{-52})\times2^{2046-1023} \\={(2-2^{-52})}\times2^{1023} EM=(211−1)−1=1⋯10=2046=1−2−52对应的真值为:max=1.M×2E−B2=(2−2−52)×22046−1023=(2−2−52)×21023
-
机器零
- 当一个浮点数
尾数为0
时(不论其阶码为何值)或阶码等于或小于它所能表示的最小数
时(不管其尾数为何值)机器都把该浮点数作为零看待,并称之为“机器零
”。 - 如果浮点数的阶码用移码表示,尾数用补码表示
- 则当阶码为它所能表示的最小数 − 2 m -2^{m} −2m(式中 m为阶码的位数,此时该浮点数已经被当作机器零)且尾数为0时,其阶码(移码)全为0,尾数(补码)也全为0,这样的机器零为000…0000
🎈移码Offset binary
-
浮点数的表示中,采用移码的原因
-
使用补码不容易直接判断数的大小
-
使用移码可以直接判断出机器数对应的真值之间的大小关系
-
移码只能够表示整数
-
-
[ x ] 移 在 数 轴 上 的 表 示 总 是 ⩾ 0 [x]_{移}在数轴上的表示总是\geqslant0 [x]移在数轴上的表示总是⩾0
-
假设:
-
真 值 x 的 移 码 的 二 进 制 串 为 O ( x ) = x 0 , x 1 ⋯ x n 真值x的移码的二进制串为O(x)=x_0,x_1\cdots{x_n} 真值x的移码的二进制串为O(x)=x0,x1⋯xn
-
O ( x ) = 2 n + x , ( x ∈ [ − 2 n , 2 n − 1 ] ) O ( x ) ∈ [ 0 , 2 n + 1 − 1 ] 以 n + 1 位 二 进 制 无 符 号 数 表 示 [ 0 ⋯ 00 2 , 1 ⋯ 11 2 ] O(x)=2^n+x,(x\in[-2^{n},2^n-1]) \\O(x)\in[0,2^{n+1}-1] \\以n+1位二进制无符号数表示[0\cdots{00}_2,1\cdots{11}_2] O(x)=2n+x,(x∈[−2n,2n−1])O(x)∈[0,2n+1−1]以n+1位二进制无符号数表示[0⋯002,1⋯112]
-
如 果 数 值 位 不 足 n 位 , 则 补 0 对 齐 如果数值位不足n位,则补0对齐 如果数值位不足n位,则补0对齐
-
计算移码的偏置值通常取的就是 2 n 2^n 2n
-
移 码 计 算 公 式 ( 移 码 函 数 O ( x ) ) 是 一 个 单 调 递 增 函 数 移码计算公式(移码函数O(x))是一个单调递增函数 移码计算公式(移码函数O(x))是一个单调递增函数
-
-
有的地方偏置值取 2 n − 1 2^n-1 2n−1
-
移码和真值相互转换以及表示范围
-
从移码计算真值:
-
x
=
O
−
1
(
O
(
x
)
)
=
O
(
x
)
−
2
n
x=O^{-1}(O(x))=O(x)-2^n
x=O−1(O(x))=O(x)−2n
- x ∈ [ − 2 n , 2 n − 1 ] x\in[-2^{n},2^n-1] x∈[−2n,2n−1]
- 此时将 O ( x ) O(x) O(x)理解为无符号数
- O ( x ) ∈ [ 0 , 2 n + 1 − 1 ] O(x)\in[0,2^{n+1}-1] O(x)∈[0,2n+1−1]
-
x
=
O
−
1
(
O
(
x
)
)
=
O
(
x
)
−
2
n
x=O^{-1}(O(x))=O(x)-2^n
x=O−1(O(x))=O(x)−2n
-
🎈相同位数n的情况下,移码可以表示的数(真值)的范围和补码一样
-
例
-
用 函 数 O ( x ) 表 示 x 的 移 码 用函数O(x)表示x的移码 用函数O(x)表示x的移码
-
真 值 x 1 = + 10100 ( 二 进 制 形 式 ) 真值x_1=+10100(二进制形式) 真值x1=+10100(二进制形式)
- 整 数 位 数 为 n 1 = 5 ( 没 有 显 式 给 定 机 器 字 长 , 自 行 通 统 计 x 的 二 进 制 形 式 的 位 数 ) 整数位数为n_1=5(没有显式给定机器字长,自行通统计x的二进制形式的位数) 整数位数为n1=5(没有显式给定机器字长,自行通统计x的二进制形式的位数)
- (如果给定了机器字长n,需要视情况将二进制数补齐到n位)
-
O ( x 1 ) = 2 n + x = 2 5 + 1010 0 2 = 100000 + 1010 0 2 = 1 , 10100 O(x_1)=2^n+x=2^5+10100_2=100000+10100_2=1,10100 O(x1)=2n+x=25+101002=100000+101002=1,10100
- 此处添加的逗号,将符号位和数值部分分割开来
- 移码不用来表示小数
-
真 值 x 2 = − 10100 ( 二 进 制 形 式 ) 真值x_2=-10100(二进制形式) 真值x2=−10100(二进制形式)
- 整 数 位 数 为 n 2 = 5 整数位数为n_2=5 整数位数为n2=5
-
O ( x 2 ) = 2 n + x = 2 5 − 1010 0 2 = 100000 − 1010 0 2 = 0 , 0110 O(x_2)=2^n+x=2^5-10100_2=100000-10100_2=0,0110 O(x2)=2n+x=25−101002=100000−101002=0,0110
-
真 值 x = ± 0 ( 二 进 制 形 式 ) 真值x=\pm0(二进制形式) 真值x=±0(二进制形式)
- 整 数 位 数 为 n 整数位数为n 整数位数为n
-
O ( ± 0 ) = 2 n ± 0 = 2 n = 2 n = 1 , 0 ⋯ 00 O(\pm0)=2^{n}\pm0=2^{n}=2^n=1,0\cdots{00} O(±0)=2n±0=2n=2n=1,0⋯00
-
可 见 , ± 0 可见,\pm{0} 可见,±0移码的表示形式是相同的,真值0的补码具有唯一性
- 此外,由移码的定义可见,当n = 5时,其最小的真值为 x = − 2 5 = − 10000 0 二 进 制 x = -2^{5}=- 100000_{二进制} x=−25=−100000二进制,则 [ − 100000 ] 移 = 2 5 + x = 100000 − 100000 = 0 , 00000 [ - 100000]_{移} =2^{5}+ x = 100000 - 100000 = 0,00000 [−100000]移=25+x=100000−100000=0,00000,即最小真值的移码为全0,这符合人们的习惯。
- 利用移码的这一特点,当浮点数的阶码用移码表示时,就能很方便地
判断阶码的大小
C语言和浮点数类型
- C语言中的浮点数类型及类型转换.
- C语言中的float和double类型分别对应于IEEE 754单精度浮点数(32bit)和双精度浮点数(64bit)。
long double
类型对应于扩展双精度浮点数,但long double
的长度和格式随编译器和处理器类型的不同而有所不
同。
- 在C程序中等式的赋值和判断中会出现强制类型转换
- 以char> int>long> double和float>double最为常见,
- 从前到后范围和精度都从小到大,转换过程没有损失。
- 从int转换为float时(通常,它们都是32bit),虽然不会发生溢出
- 但int可以保留32位,float保留24位(包括隐藏位),可能有数据舍入(可能影响精度)
- 具体是:当int类型的 25 ∼ 31 25\sim{31} 25∼31bit这些位非0,就无法被无损的转换为浮点数
- 因此,如果可以用整形表示的数尽量用整形,不经可以保证精度也可以保证运算效率
- 若从int转换为double则不会出现精度受损
- 应为double类型的精度达到53位明显大于31位(不计符号位)
- double的有效位数更多,因此能保留精确值。
- 因此不能够笼统的认为,整数转为浮点数,精度一定下降(要区分单精度和双精度)
- 就算是单精度,也要考虑被转换的数的结构!
- 应为double类型的精度达到53位明显大于31位(不计符号位)
- long到double同样可能会损失精度(但是不总是损失,以被转换的数据小数情况共同考虑)
- 但int可以保留32位,float保留24位(包括隐藏位),可能有数据舍入(可能影响精度)
- 从double 转换为float 时,因为float 表示范围更小,因此可能发生溢出。
- 此外,由于有效位数变少,因此可能被舍入。
- 从float或double转换为int时,因为int没有小数部分
- 所以数据可能会向0方向被截断(仅保留整数部分),影响精度。
- 浮点数x向0方向阶段,就是绝对值被向下取整了
- 123.45 → 123 123.45\to{123} 123.45→123
- − 123.45 → − 123 -123.45\to{-123} −123.45→−123
- 另外,由于int的表示范围更小,因此可能发生溢出。
- 31位数值位的上限 2 31 − 1 2^{31}-1 231−1
- 单精度的float具有8位阶码(7位数值位,上限为 2 2 7 − 1 = 2 127 2^{2^{7}-1}=2^{127} 227−1=2127
- 双精度的范围就更大了,达到 2 1023 2^{1023} 21023
- 可见差距十分悬殊
- 所以数据可能会向0方向被截断(仅保留整数部分),影响精度。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」