0x39A7F8
0011 1001 1010 0111 1111 1000
A 9 7 B
1101 0101 1110 0100 1100
补0: 0010 0110 1110 0111 1011 0101
转:2 6 E 7 B 5
n | 2 n 2^n 2n(十进制) | 2 n 2^{n} 2n(十六进制) |
---|---|---|
9 | 512 | 0x200 |
19 | 1028*512 = 524288 | 0x80000 |
14 | 16384 | 0x4000 |
16 | QwQ,不想算 | 0x10000 |
17 | 不想算 | 0x20000 |
5 | 32 | 0x20 |
7 | 128 | 0x80 |
方法: 当二进制表示为 2 n 2^n 2n次方时,十六进制如果可以写为 i + 4 j i+4j i+4j,则十六进制可以写为 0 x 2 i ( 0..0 ⏟ j 个 0 ) 0x2^i(\underbrace{0..0}_{j个0}) 0x2i(j个0 0..0)
以 2 9 2^9 29为例子, 9 = 2 × 4 + 1 9 = 2\times 4+1 9=2×4+1,则可以表示为 0 x 200 0x200 0x200
十进制 | 二进制 | 十六进制 |
---|---|---|
0 | 0000 0000 | 0x00 |
167 | 1100111 | 0x67 |
62 | 111100 | 0x3C |
188 | 1111100 | 0x7C |
55 | 0011 0111 | 0x37 |
136 | 1000 1000 | 0x88 |
243 | 1111 0011 | 0xF3 |
82 | 0101 0010 | 0x52 |
172 | 1010 1100 | 0xAC |
251 | 1110 0111 | 0xE7 |
Tip: 将十进制加减法规则应用于16进制,仅需将基数改为16,加减法时也需要注意满为16
0 x 503 c + 0 x 8 = 0 x 5044 0 x 503 c − 0 x 40 = 4 f f c 0 x 503 c + 64 = 0 x 505 c 0 x 50 e a − 0 x 503 c = 0 x a d \begin{aligned}0x503c + 0x8 &= 0x5044 \\0x503c - 0x40 &= 4ffc\\0x503c + 64 &= 0x505c\\0x50ea - 0x503c &= 0xad\end{aligned} 0x503c+0x80x503c−0x400x503c+640x50ea−0x503c=0x5044=4ffc=0x505c=0xad
typedef unsigned char* pointer_char;
void show_bytes(pointer_char x, int len){
for(int i=0; i<len; ++i){
printf("%.2x", x[i]);
}
}
目前的big-endian 只存在sun系统及互联网协议中,因此在socket通信中需要将big-endian–>little endian来通信
题目要求的是输出三次递增1 2 3
位的字长,则有:
Big-Endian | Little-Endian |
---|---|
65 | 21 |
65 43 | 21 43 |
65 43 21 | 21 43 65 |
因为机器不是sun的及浮点还没学,就不误导大家了qwq
show_bytes函数与2.5相同
输出结果为:
"abcdefg"
61 62 63 64 65 66 67
知:a~z的ascii码为0x61~0x7A
Imp: ascii字符码在任何系统上的结果都是一样的,与word size||字节大小规则无关
运算 | 结果 |
---|---|
a | [01101001] |
b | [01010101] |
~a | [10010110] |
~b | [10101010] |
a&b | [01000001] |
a|b | [01111101] |
a^b | [00111100] |
可能疑惑: 将逻辑运算视为set运算,关于**^逻辑表示为异或**(对称求解)
位向量(集合)间补的运算即为求反~[vec]
R | G | B | 颜色 | R | G | B | 颜色 |
---|---|---|---|---|---|---|---|
0 | 0 | 0 | 黑色 | 1 | 0 | 0 | 红色 |
0 | 0 | 1 | 蓝色 | 1 | 0 | 1 | 红紫色 |
0 | 1 | 0 | 绿色 | 1 | 1 | 0 | 黄色 |
0 | 1 | 1 | 蓝绿色 | 1 | 1 | 1 | 白色 |
求对应向量的反码后,根据表找到对应的补即可
根据上述2.8的规则求也成了(我是懒doge)
数电里也提到过,0 ^ […] = […], 1 ^ […] = ~[…]
根据程序:
void replace(int *x, int *y){
*y = *x^*y;
*x = *x^*y;
*y = *x^*y;
}
得:
Step | *x | *y |
---|---|---|
Initial | a | b |
Step 1 | a | a^b |
Step 2 | a(ab) = 0^b=b | a^b |
Step 3 | b | b(ba) = 0^a = a |
题目太长,我选择不抄(懒doge again
first
Requests:
- 除了x的最低有效字节,其他都需要全为0;
- 最低有效字节不变,其他的位取补
- 最低有效字节设置为1,其他字节保持不变
一开始的做法错了,想用字节数组输出,但是这个好傻qwq,并且我没实现orz
然后再看一遍题目,随机玩了玩移位,才感觉到这道题需要用的是逻辑运算…
int num = 0x87654321;
/*A*/
printf("%.8x\n", num&(0xFF));
/*B*/
printf("%.8x\n", num^(0x11111100));
/*C*/
printf("%.8x\n", num|(0x000000FF));
根据逻辑运算就可以得出啦
要求: 只能用逻辑运算,理解一下即bis把m为1的位置,z对应的位也设为1;bic则把m为1的位置,z设为0.最后用bis和bic实现|及^运算
int bis(int x, int m){
return x|m;
}
int bic(int x, int m){
return x&(~m);
}
/*calculation of '|'*/
int bool_or(int x, int y){
return bis(x, y);
}
/*calculation of '^'*/
int bool_xor(int x, int y){
return bis(bic(x,y),bic(y,x));
}
**问题:**在一开始实现异或时没有考虑 x = 0 , m = 1 x=0,m=1 x=0,m=1的情况,如果只用bic来实现的话输出的仅为0,但实际应该是1
注意这里如果笔算,建议先将16进制转为二进制,进行集合的运算后能更快得到结果
表达式 | 值 |
---|---|
x & y | 0x20 |
x | y | 0x7F |
~x | ~y | 0xDF |
x & !y | 0x00 |
x && y | 0x01 |
x || y | 0x01 |
!x || !y | 0x00 |
x && ~y | 0x01 |
对应程序:
int x = 0x66, y = 0x39;
printf("x&y = %x\n", x&y);
printf("x|y = %x\n", x|y);
printf("~x|~y = %x\n", ~x|~y);
printf("x&!y = %x\n", x&!y);
printf("x&&y = %x\n", x&&y);
printf("x||y = %x\n", x||y);
printf("!x||!y = %x\n", !x||!y);
printf("x&&~y=%x\n", x&&~y);
突然发现练习题后面有答案qwq…