深入理解计算机系统¶
- katex支持参考: https://katex.org/docs/supported.html
- katex上下标: https://zhuanlan.zhihu.com/p/262907455
信息的表示和处理¶
位向量¶
markdown 数学公式参考: https://www.jianshu.com/p/4460692eece4 、 https://www.jianshu.com/p/8b6fc36035c0
原文:P36
位向量就是固定长度为 w
、由0
和1
组成的串。
位向量的运算是布尔代数运算的扩展,可以被定义为参数的每个对应元素之间的运算。假设 a 和 b分别表示位向量\([a_{w-1}, a_{w-2}, ..., a_0 ]\)和\([b_{w-1}, b_{w-2}, ..., b_0 ]\)。我们将\(a \And b\)也定义为一个长度为\(w\)的位向量,其中第\(i\)个元素等于\(a_i \And b_i, 0 \le i \lt w\)可以用类似的方式将 ~ , ! , ^ 扩展到位向量上。
位向量的一个妙用就是表示有限集合。我们可以用位向量\([a_{w-1}, a_{w-2}, ..., a_1, a_0 ]\)编码任何子集\(A \subset \{ 0, 1, ..., w - 1 \}\),其中\(a_i = 1 \iff i \in A\).
举个栗子,位向量\(a = [01101001]\)表示集合\(A = \{ 0, 3, 5, 6 \}\),而\(b = [01010101]\)表示集合\(B = \{ 0, 2, 4, 6 \}\)。
用这种编码集合的方法,布尔运算|
和&
分别对应集合的并和交,而~
对应集合的补运算。
还是用前面那个例子,运算\(A \And B \(得到位向量\)[01000001]\), 而\(A \And B = \{ 0, 6 \}\)。
-
也就是在这种规则下说
位运算
里面的\(a \And b\)对应 数学集合运算里面的交集(\(\cap\))。 -
关于\(a = [01101001]\)代表集合\(A = \{ 0, 3, 5, 6 \}\), 即表示
a
集合中位置第0
、3
、4
、6
位时为二进制的0
,所以表示为集合A
.
查资料之后我的理解:
X ^ Y
异或运算,有一个为真,但不同时为真,则结果为真
,否则结果为假。~ X
取反运算,为假时结果为真,为真时结果为假。x & Y
与运算,同时为真时结果取真,否则结果为假。X | Y
或运算,有一个为真时结果取真,否则结果为假。
补码的取值方式: 0异或是对方,1异或是对方的补.
例子:
X = 01101001 # 原字节序列
Y = 11111111 # 全数字1
Z = 00000000 # 全数字0
~ X = 10010110 # 取反(~)运算 补运算
X ^ Y = 10010110 # 异或1运算,是 X 的补
X ^ Z = 01101001 # 异或0运算,是 X 自己
习题 2.12 写出变量x的C语言表达式¶
对于下面的值,写出变量X的C语言表达式。你的代码应该对任何字长W大于等8都能工作。我们给出了当X=0x87654321以及w=32时表达式求值的结果,仅供参考。
- A. x的最低有效字节,其他位均置为0。【0x00000021】.
- B. 除了X的最低有效字节外,其他的位都取补,最低有效字节保持不变。【0x789ABC21】。
- C. x的最低有效位设置为全1,其他字节都保持不变。【0x876543FF】。
#include<stdio.h>
void convert(unsigned int var)
{
printf("0x%.2x", var);
printf("\n");
// A答案
int a = var & 0xFF;
printf("0x%.2x", a);
printf("\n");
// 校验
unsigned int b = 0;
printf("0x%.2x", (~ b));
printf("\n");
// B答案
// printf("0x%.2x", ((~ var) ));
// printf("\n");
// printf("0x%.2x", ((~ var) & 0xFF ));
// printf("\n");
// printf("0x%.2x", ((~ var) & 0xFF ) | var);
// printf("\n");
// printf("0x%.2x", ~(((~ var) & 0xFF ) | var));
// printf("\n");
// printf("0x%.2x", (~(((~ var) & 0xFF ) | var)) | (var & 0xFF));
// printf("\n");
// C答案
printf("0x%.2x", ((~ var) ));
printf("\n");
printf("0x%.2x", ((~ var) & 0xFF ));
printf("\n");
printf("0x%.2x", ((~ var) & 0xFF ) ^ var);
printf("\n");
return 0;
}
int main()
{
printf("**************************\n");
printf("dotcpp.com\n");
printf("**************************\n");
convert(0x87654321);
return 0;
}
输出结果
**************************
dotcpp.com
**************************
0x87654321
0x21
0xffffffff
0x789abcde
0xde
0x876543ff
确定大小整型的更多内容¶
P47
#include<stdio.h>
#include<stdint.h>
#include<inttypes.h>
int main()
{
printf("**************************\n");
printf("dotcpp.com\n");
printf("**************************\n");
printf("0x%.2x", (~ -1));
printf("\n");
// 宏定义在头文件 <stdint.h> 中 , 确定int类型和 uint类型的字节数,无歧义声明,以保证可移植性
int32_t x = 23123123; // 指定位数声明
uint64_t y = 551241243123; // 指定位数声明
// PRId32 和 PRIu64的宏定义在<inttypes.h>中
printf("x = %" PRId32 ", y = %" PRIu64 "\n", x, y);
//小写字母输出
printf("x = 0x%032x" ", y = 0x%064x" "\n", x, y);
//大写字母输出
printf("x = 0x%032X" ", y = 0x%064X" "\n", x, y);
return 0;
}
创建日期: 2023年2月23日