Lecture 02 Bits, Bytes, and Integer

通过位可以表示集合

例如,一个 8 位的二进制数 01101001 ,可以用于表示一个全集为 {0,1,2,3,4,5,6,7} 的集合 {0,3,5,6}

  • 01101001
  • 76543210

通过上面的一一对应关系可以确认集合中的元素。
通过这种表示方法,二进制的位运算可以转换为集合之间的运算:

符号 位运算 集合运算
& 交集
| 并集
^ 异或 对称差
~ 补集

通过逻辑运算符的短路特性可以避免访问空指针

int *p;
if (p && *p) {
    ...
}

p 为空指针时,会直接返回 0,当 p 不为空指针时,才会对 p 的值进行判断。

位移运算

当进行位移运算时,向左位移只有唯一一种情况,而向右位移有两种情况,分为逻辑位移和算数位移。两种右位移的区别是填充方式不同。

位移方式 填充
左位移 0
逻辑右位移 0
算数右位移 符号位( 01 )

举例如下:

运算方式 二进制表示
x 01100010
<< 3 00010000
Log.>> 2 00011000
Arith.>> 2 00011000
运算方式 二进制表示
x 10100010
<< 3 00010000
Log.>> 2 00101000
Arith.>> 2 11101000

补码的实际含义

在有符号整数的计算过程中,将最高位作为负数进行计算,即可直接得到补码,而不需要取反再加一。
用5位数举例如下:

4 3 2 1 0
原码 16 8 4 2 1
补码 -16 8 4 2 1
  • 假设一个数为 (10110)2,即 (10)10
  • 正常方式计算:补码 10110 => 反码 10101 => 原码 11010 => 8+(2)=10
  • 新算法:补码 10110 => 16+4+2=10

通过这种方式可以更好理解补码编码后的极值问题。例如只有 5 位的情况下,只有第一位表示负数,因此最小的负数一定是 10000, 而最大的正数一定是 01111

无符号整数和有符号整数的转换关系

存在如图的映射关系,其中 TMax 为有符号整数上限,TMin 为有符号整数下限,UMin 为无符号整数上限
image

UMax=2TMax+1的解释

TMax=011...1
2TMax=TMax<<1=11...10
2TMax+1=11...11=UMax

编程时可能出现的问题

i 为无符号整数时
for (i = n - 1; i >= 0; i--) {...}
由于 i0 时,再次减一会得到 UMax,因此该循环将不会结束。
当循环条件中出现sizeof(返回值为size_t,无符号)时容易出现该问题,如:
for (int i = n - 1; i - sizeof(char) >= 0; i--) {...}
此时由于sizeof(char)为无符号,因此运算时 i 会被转换为无符号整数,循环变为死循环。

符号位拓展

可以使用任意位作为符号位,不会影响数值大小。
当该数为正数时,填充符号位填充的数为 0,不影响大小。
当该数位负数时,填充符号位填充的数为 1,假设该数有 n 位:
计算补码可以发现,新填充的 1 表示的数为 2n,原本的符号位 1 表示的数为 2n1,两者相加会得到 2n1,与原符号位相同,因此也不影响大小。
举例:

  • 原数为 (0110)2,即 (3)10
  • 扩充一位后得到 (00110)22+1=(3)10
  • 原数为 (1110)2,即 (2)10
  • 扩充一位后得到 (11110)28+4+2+1=(2)10

该操作也解释了右移位时算数移位的意义,即将右移位作为除 2n 的除法时,填充 1 才会得到正确的除法结果。

二进制截断

对于无符号整数,截断二进制的后 n 位相当于对 2n 取模。

  • 对于 (11011)2,即(27)10截断其后 4 位,得到 (1011)2,即 (11)10,相当于对 24=16 取模。
    对于有符号整数,没有计算方面的关联性,但是将其转换为无符号整数后可以进行相同的取模操作。
posted @   _Konnyaku  阅读(20)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
点击右上角即可分享
微信分享提示