版权声明:本文为 gfson
原创文章,转载请注明出处。
注:作者水平有限,文中如有不恰当之处,请予以指正,万分感谢。
1. 无符号数加法和算术溢出
- 检测无符号数加法中的溢出
2. 无符号数的加法逆元
3. 补码加法和溢出
- 检测补码加法中的溢出
4. 两个练习题
- 答案:
在函数的测试过程中,应该考虑 TMin 的情况。
5. 补码的非
- 补码非的位级表示
计算补码非位级表示的两种方法:
- 对每一位求补,再对结果加 1。既:-x = ~x + 1。
- 先定位最右边的 1,将这个 1 的左边所有位取反。
6. 无符号数和补码的乘法
- 练习:
- 如果需要打印 int64_t 的话,需要使用 %lld 或者:
int64_t t;
printf("%" PRId64"\n", t);
宏 PRId64 在 inttypes.h
中定义。
- 思考:碰到判断溢出的问题时,可以考虑强制类型转化后值是否会变来判断。
7. 乘以常数
- 可以使用移位和加法运算的组合来替代乘以常数因子的乘法。
- 大多数编译器在只需要少量移位、加法和减法就足够的时候才使用这种优化。
8. 除以 2 的幂
- 整数除法总是舍入到零,既向下舍入一个正值,向上舍入一个负值。
- 对于无符号数,使用逻辑右移,x >> k 即可表示除以 2 的幂。
- 对于补码,使用算术右移:
- x >= 0 时,x >> k 即可表示除以 2 的幂。
- x < 0 时,为了达到向上舍入一个负值的目的,需要在右移之前加上一个偏移量。
加偏移量的原理为:- 对于整数 x 和 y(y > 0),[ x / y ] 上界 = [ (x + y - 1) / y ] 下界。
- 总结,对于使用算术右移的补码机器来说:
- C 表达式 ( x < 0 ? x + ( 1 << k ) - 1 : x ) >> k 将会计算数值 x / 2 x 。
9. 练习题
- 答案:
技巧:
- 表达式 x>>31 产生一个字,如果 x 是负数,这个字全为 1,否则全为 0。
- 通过掩码
& 0xF
的方式,达到期望的偏置值。
- 答案:
思考:
- 任何时候需要考虑 TMin 的情况。
- 需要考虑溢出的情况,特别是遇到乘法时。
- 当有符号数与无符号数一起运算时,会默认先转化为无符号数运算,如题中 F 所示。
- 无符号数和补码乘法结果的位级表示是一样的。既,虽然完整位级表示可能不一样,但是截断后的位级表示是一样的。