2.1.1 十六进制表示法

2的整数幂转化为16进制:

多少次方就有多少个零。

\(2048 = 2^{11}\) \(n = 11 = 3 +4*2\)

因此十六进制表示为0x800。

2.1.2 字数据大小

计算机字长等于指针数据的长度,32/64。

2.1.3 寻址和字节顺序

typedef unsigned char *byte_pointer;

void show_bytes(byte_pointer start, size_t len)
{
	size_t i;
	for (int i = 0; i < len; i++)
		printf("%.2x\n", start[i]);
}

int val = 0x87654321
byte_pointer valp = (byte_pointer)&val;
show_bytes(valp, 1);
// 结果是0x21, 小端法低地址保存的是数据低有效位

const char *s = "12345";
show_bytes((byte_pointer)s, strlen(s));
// 结果是31 32 33 34 35。没有字符串结尾的00,因为strlen不统计结束符。
// 注意字符串会以顺序排列,和字节序无关。

2.1.9 C语言中的移位运算

逻辑右移和算术右移。
算术右移是在左端补k个最高有效位的值。

几乎所有的编译器都对有符号数使用算术右移。
对无符号数必须是逻辑右移动。

如果移位k的大小大于字长w,大部分c程序会用k mod w作为移动的长度:

int lval = 0xfedcba98 << 32;
int aval = 0xfedcba98 >> 36;

lval: 0xfedcba98
aval: 0xffedcba9

2.2.4 有符号数和无符号数之间的转换

强制类型转换结尾保持位值不变,只是改变了解释这些位的方式。

补码转无符号数: \(if\space x < 0: x = x+2^w\) \(if\space x >= 0: x = x\)

无符号数转补码: \(if\space u < TMax_u: u = u\) \(if\space x >= TMax_u: u = u-2^w\)

2.2.5 C语言中的有符号数和无符号数

声明一个像12345, 0x1A2B, 默认是有符号数。
创建无符号常量需要加上U, 12345U, 0x1A2Bu。

当执行一个运算时,如果它的一个运算数是有符号的,而另一个是无符号的,那么C会将有符号数强制转换为无符号数。

e.g. -1<0U,int -1会被转化为4294967295U<0U导致错误。

2.2.6 扩展数字

无符号数:零扩展
有符号数:符号扩展

大小符号都不同的扩展,比如short转换成unsigned int:
先进行符号扩展,再改变大小,再进行符号转换。

short sx = -12345; // cf c7
unsigned int uy = sx;
// uy = ff ff cf c7
// uy = 4294954951

2.4 浮点数

// TODO: