系列文章目录
信息的表示和处理 :
- Information Storage(信息存储)
- Integer Representation(整数表示)
- Integer Arithmetic(整数运算)
- Floating Point(浮点数)
文章目录
- 系列文章目录
- 前言
- 一、无符号数的加法(Unsigned Addition)
- 二、无符号数加法逆元
- 三、补码的加法(Two's Complement Addition)
- 四、补码的逆元
- 五、乘法
- 六、乘以常数(Multiply by Constants)
- 七、除以2(Dividing by Powers of 2)
- 总结
- 参考文献:
前言
本文参考书籍是《深入理解计算机系统 3th 中文版》,本文的图片大多是参考和来自于b站up主九曲阑干。非常感谢大佬,侵权删。
本篇文章会提到部分整数数据和算数操作的术语,详情可见2.整数表示的前言部分。
一、无符号数的加法(Unsigned Addition)
先来看一个例子:
unsigned char a = 255;
unsigned char b = 1;
unsigned cahr c = a + b;
printf("c = %d", c)
运行结果: c = 0
下面是这样一个无符号数加法的总结性结论:
考虑溢出,C 语言不会将溢出作为错误发出信号
当 x+y >= 2^w, 实际结果为 s = x+y-2^w
对任意的 x+y,s = (x+y) % 2^w
上述代码是判断是否溢出,证明略
二、无符号数加法逆元
根据逆元的定义好理解,但是从常识来讲不好理解
三、补码的加法(Two’s Complement Addition)
正溢出:
char x = 127;
char y = 1;
char z = a + b;
printf("z=%d", z);
运行结果:z = -128
解释:
负溢出:
如何判断溢出:
四、补码的逆元
这个知识点是没啥用又不太好理解的知识点,略过
五、乘法
正常的乘法:
无符号数的乘法:
补码的乘法:
举一个3-bit的乘法:
可以看到,当相同的二进制位(binary)它们分别用不同的表示方式(无符号数,补码)相乘,在位层面上是一样的吗?
证明:
六、乘以常数(Multiply by Constants)
相当于10进制里面移动小数点
为什么会这样???
举一个例子:
七、除以2(Dividing by Powers of 2)
注意:补码和无符号数的右移
证明略
这里有个特殊点:
这里我们期望得到的是-771而不是-772(直接向右算数移动四位)。
首先,我们为什么这么期望?因为有如下规则(向0舍弃):
为了满足这种规则,如果x小于0,移位之前要加上一个bias
这个bias的值是( 1 << k ) - 1
总结
- 无符号数加法可能会导致溢出
- 无符号数的加法逆元和补码逆元(鸡肋)
- 补码的加法:
- 正溢出
- 负溢出
- 无符号数的乘法,和补码的乘法
- 乘以常数,可以用左移。甚至可以拆分常数将其弄成
2^k
的组合形式 - 除以
2^k
:- 正数就逻辑右移
- 负数加上bias再算数右移(bias的作用就是使得结果向0舍入)
- 上面的乘以和除以
2^k
就可以用小数点移位去理解,就相当于是10进制中的乘和除以10^k
参考文献:
- 《深入理解计算机系统 3th 中文版》
- b站up主九曲阑干