C语言中补码的整数运算特性

前言

本篇博客以“SSD6-Exercise2-Data Lab: Manipulating Bits”为例,分析在对C语言中的整数采用补码(two’s-complement)编码的机器上,其整数运算的特性。


补码

定义

最常见的有符号数的计算机表示方式就是补码(two’s-complement)形式。在这个定义中,将字的最高有效位解释为负权(negative weight),我们用函数B2T(Binary to Two’s-complement的缩写,长度为 w)来表示。

如:

B2T ([0001]) = -0 + 0 + 0 + 1 = 1
B2T ([0101]) = -0 + 4 + 0 + 1 = 5
B2T ([1011]) = -8 + 0 + 2 + 1 = -5
B2T ([1111]) = -8 + 4 + 2 + 1 = -1

定理1

B2T ([11···1]) = -1

证明:假设B2T ([11···1]) 共有w位,则其值为 -2^(w-1) + 2^(w-2) + ··· + 2^0. 根据等比数列求和公式,易证该值为-1.

定理2

对于w位的补码B2T来说,其边界值Tmax与Tmin分别为:

Tmax = B2T ([01···1]) = 2^(w-1) - 1

Tmin = B2T ([10···0]) = -2^(w-1)

即有:~Tmax = Tmin


整数运算

我们先以表格的形式,宏观介绍C语言中的位级运算、逻辑运算和移位运算。

运算种类 运算符 主要说明
位级运算 |, &, ~, ^ 对应于布尔运算中的OR, AND, NOT, EXCLUSIVE-OR
逻辑运算 ||, &&, ! 对应于命题逻辑中的OR, AND, NOT
移位运算 <<, >> 分为左移与右移,右移运算包括逻辑右移与算数右移
!~有什么区别?

注意:逻辑运算很容易和位级运算相混淆,但是它们的功能是完全不同的。

  • 逻辑运算中认为所有非零的参数都表示TRUE,而参数0表示FALSE.

  • 逻辑运算的结果为一个布尔值,而位级运算的结果依然为一个.

  • 逻辑运算的运算符常称为,而位级运算的运算符常称为取反异或.

因此,!是逻辑运算中的运算符,而~是位级运算中的取反运算符。

逻辑右移与算术右移

我们先来看左移运算<<.

对操作数x执行x<<k运算,即x向左移动k位。此运算会丢弃最高的k位,并在右端补k0.

相应而言的右移运算>>.

对操作数x执行x>>k运算,即x向右移动k位。此运算会丢弃最低的k位,那么在左端需要补充的k个位是什么呢?

若执行逻辑右移,则补充k0,这类似于左移运算.

若执行算术右移,则补充k最高有效位的值。

且几乎所有的编译器/机器组合都对有符号数使用算术右移,对无符号数采用逻辑右移。


运算特性

我们通过完成这下面这10个函数,来体会补码的整数运算特性。

/* 
 * bitAnd - x&y using only ~ and | 
 *   Example: bitAnd(6, 5) = 4
 *   Legal ops: ~ |
 *   Max ops: 8
 *   Rating: 1
 */
int bitAnd(int x, int y) {
    return ;
}

/* 
 * bitOr - x|y using only ~ and & 
 *   Example: bitOr(6, 5) = 7
 *   Legal ops: ~ &
 *   Max ops: 8
 *   Rating: 1
 */
int bitOr(int x, int y) {
    re
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值