%%
# 纲要
> 主干纲要、Hint/线索/路标
# Q&A
#### 已明确
#### 待明确
> 当下仍存有的疑惑
**❓<font color="#c0504d"> 有什么问题?</font>**
# Buffer
## 闪念
> sudden idea
## 候选资料
> Read it later
%%
# 无符号整数的表示
计算机中对于**无符号整数**使用 **==直接的二进制表示==**——给定位宽下,**所有二进制位均用于表示数值本身,没有符号位**。
给定二进制位宽 $w$,可表示的**无符号整数范围为 $[0, 2^w-1]$**。
<br><br>
# 无符号整数的运算
**给定位宽 $w$** 下,**无符号整数运算即为==模 $2^w$ 运算==**($\text{mod}\;\;2^w$),当**运算结果超出可表示范围时会==从 0 开始回绕==**。
<br>
### 无符号数加法
**==无符号数加法==($w$ 位宽下)**:**两个无符号数的==二进制表示做二进制加法并舍弃最高位进位**==,所得的二进制位模式再直接解释为无符号整数。
$
[X+Y]_{\text{BitPattern}}=[X]_{\text{BitPattern}}+[Y]_{\text{BitPattern}}
$
就运算结果而言,**$w$ 位宽下的无符号数加法**即 **"模 $2^w$ 加法**"——**若结果大于 $2^{w}-1$,就将结果减去 $2^w$
![[_attachment/02-开发笔记/03-计算机基础/数据的编码表示/无符号整数的表示.assets/IMG-无符号整数的表示-F752340D8F494A83856E983784B47C01.png|575]]
![[_attachment/02-开发笔记/03-计算机基础/数据的编码表示/无符号整数的表示.assets/IMG-无符号整数的表示-2227E2581D0B9355BCE414FF800A0DD7.png|325]]
> [!example] 无符号整数加法示例 (8 位宽)
>
> - $1\;[0000\;0001]+255\;[1111\;1111]=0\;[0000\;0000]$ 溢出
> - $255\;[1111\;1111]+255\;[1111\;1111]=254\;[1111\;1110]$ 溢出
<br>
### 无符号数减法
**==无符号整数减法==**(给定位宽下):**转换为加法运算**, $X-Y => X+(-Y)$ ,**对 $X$ 和 $-Y$ 做二进制加法**:
$
[X-Y]_{\text{BitPattern}}=[X]_{\text{BitPattern}}+[-Y]_{\text{BitPattern}}
$
> [!important] 无符号数的二进制表示求反
>
> ![[_attachment/02-开发笔记/03-计算机基础/数据的编码表示/无符号整数的表示.assets/IMG-无符号整数的表示-77B10C9B8F55B032F5BC49CE89F56D8D.png|475]]
>
> 在实际硬件计算中,$a-b$ 通过==转换为**$a$ 加上 $b$ 的补码 $b_{补数}$ 实现**==,即 $a-b=a+b_{补数}=a+(2^w-b)$
>
> 其中,$b_{补数}=2^{w}-b$ 可**由 $b$ 的二进制表示==取反加一==得到**。
就运算结果而言,**$w$ 位下的无符号数减法**即 "**模 $2^w$ 减法**":当**被减数小于减数时,将结果加上 $2^w$。
> [!example] 无符号整数减法示例 (8 位宽)
>
> - $0\;[0000\;0000]-1\;[0000\;0001]=0\;[0000\;0000]+(-1\;[1111\;1111])=255\;[1111\;1111]$ 溢出
> - $0\;[0000\;0000]-255\;[1111\;1111]=0\;[0000\;0000]+(-255\;[0000\;0001])=1\;[0000\;0001]$ 溢出
> - $1\;[0000\;0001]-2\;[0000\;0010]=1\;[0000\;0001]+(-2\;[1111\;1110])=255\;[1111\;1111]$ 溢出
> - $1\;[0000\;0001]-255\;[1111\;1111]=1\;[0000\;0001]+(-255\;[0000\;0001])=2\;[0000\;0002]$ 溢出
> - $2\;[0000\;0002]-255\;[1111\;1111]=2\;[0000\;0002]+(-255\;[0000\;0001])=3\;[0000\;0003]$ 溢出
> - $253\;[1111\;1101]-255\;[1111\;1111]=253\;[1111\;1101]+(-255\;[0000\;0001])=254\;[1111\;1110]$ 溢出
> - $254\;[1111\;1110]-255\;[1111\;1111]=254\;[1111\;1110]+(-255\;[0000\;0001])=255\;[1111\;1111]$ 溢出
>
<br>
### 无符号数乘法
**$w$ 位下的无符号数乘法**即 "**模 $2^w$ 乘法**":当**被结果超出可表示范围时,取 $\operatorname{mod}\;2^w$;
![[_attachment/02-开发笔记/03-计算机基础/数据的编码表示/无符号整数的表示.assets/IMG-无符号整数的表示-B8AF7AF33E97AE5805F2A706CD495870.png|575]]
<br><br><br>
# 无符号整数运算的溢出
**无符号整数运算的溢出结果仍然是非负的,因此==不区分正/负溢出==,只称为"溢出"。**
> [!summary] 无符号整数运算的溢出判断
>
> 对于两个无符号数 $a$ 与 $b$ 之间的运算:
>
> - 对于无符号整数**加法**,如果**结果小于任一加数**,则说明发生了溢出。
> - 对于无符号整数**减法**,如果**被减数小于减数**,则发生溢出。
> - 对于无符号整数**乘法**,如果 $a\ne0$ 且 $\large \frac{\text{result}}{a}\ne b$,则发生溢出。
> - 对于无符号整数**除法**,不会发生溢出。
##### 无符号整数加法的溢出判断
```cpp title:
bool unsigned_add_overflow (unsigned int a, unsigned int b) {
unsigned int res = a + b;
return res < a || res < b;
}
```
##### 无符号整数减法的溢出判断
```cpp
bool unsigned_subtract_overflow(unsigned int a, unsigned int b) {
return a < b;
}
```
##### 无符号整数乘法的溢出判断
```cpp
bool unsigned_multiply_overflow(unsigned int a, unsigned int b) {
return a != 0 && result / a != b;
}
```
<br><br><br>
# 参考资料
# Footnotes