c语言补码运算程序,C语言中补码的整数运算特性之bits.c的完善

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

定理一

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

定理二

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

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

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

即有:~Tmax = Tmin

逻辑右移与算数右移

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

对操作数x执行x<

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

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

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

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

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

bits.c 文件

/*

* bits.c - Source file with your solutions to the Lab.

* This is the file you will hand in to your instructor.

*/

#include "btest.h"

#include

/*

* Instructions to Students:

*

* STEP 1: Fill in the following struct with your identifying info.

*/

info_struct info =

{

/* Replace with your full name */

"许文帅",

/* Replace with your login ID */

"2017141463051",

};

#if 0

/*

* STEP 2: Read the following instructions carefully.

*/

You will provide your solution to the Data Lab by

editing the collection of functions in this source file.

CODING RULES:

Replace the "return" statement in each function with one

or more lines of C code that implements the function. Your code

must conform to the following style:

int Funct(arg1, arg2, ...) {

/* brief description of how your implementation works */

int var1 = Expr1;

...

int varM = ExprM;

varJ = ExprJ;

...

varN = ExprN;

return ExprR;

}

Each "Expr" is an expression using ONLY the following:

1. Integer constants 0 through 255 (0xFF), inclusive.

***You are not allowed to use big constants such as 0xffffffff***

2. Function arguments and local variables (no global variables).

3. Unary integer operations ! ~

4. Binary integer operations & ^ | + << >>

Some of the problems restrict the set of allowed operators even further.

Each "Expr" may consist of multiple operators. You are not restricted to

one operator per line.

You are expressly forbidden to:

1. Use any control constructs such as if, do, while, for, switch, etc.

2. Define or use any macros.

3. Define any additional functions in this file.

4. Call any functions.

5. Use any other operations, such as &&, ||, -, ?, or []:

6. Use any form of casting.

You may assume that your machine:

1. Uses 2s complement, 32-bit representations of integers.

2. Performs right shifts arithmetically.

3. Has unpredictable behavior when shifting an integer by more

than the word size.

EXAMPLES OF ACCEPTABLE CODING STYLE:

/*

* pow2plus1 - returns 2^x + 1, where 0 <= x <= 31

*/

int pow2plus1(int x) {

/* exploit ability of shifts to compute powers of 2 */

return (1 << x) + 1;

}

/*

* pow2plus4 - returns 2^x + 4, where 0 <= x <= 31

*/

int pow2plus4(int x) {

/* exploit ability of shifts to compute powers of 2 */

int result = (1 << x);

result += 4;

return result;

}

NOTES AND HINTS:

1. Each function has a maximum number of operators (! ~ & ^ | + << >>)

that you are allowed to use for your implementation of the function.

The max operator count will be checked by your instructor.

Note that ‘=’ is not counted; you may use as many of these as you

want without penalty.

2. Use the btest test harness to check your functions for correctness.

#endif

/*

* STEP 3: Modify the following functions according the coding rules.

*/

/*

* 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 ~(~x | ~y);

}

/*

* bitOr - x|y using only ~ and &

* Example: bitOr(6, 5) = 7

* Legal ops: ~ &

* Max ops: 8

* Rating: 1

*/

int bitOr(int x, int y) {

/*德摩根定律*/

return ~(~x & ~y);

}

/*

* isZero - returns 1 if x == 0, and 0 otherwise

* Examples: isZero(5) = 0, isZero(0) = 1

* Legal ops: ! ~ & ^ | + << >>

* Max ops: 2

* Rating: 1

*/

int isZero(int x) {

/*异或:每一位 同则零异则一;*/

return !(x ^ 0);

}

/*

* minusOne - return a value of -1

* Legal ops: ! ~ & ^ | + << >>

* Max ops: 2

* Rating: 1

*/

int minusOne(void) {

/*定理一*/

return ~0;

}

/*

* TMax - return maximum two's complement integer

* Legal ops: ! ~ & ^ | + << >>

* Max ops: 4

* Rating: 1

*/

int tmax(void) {

/*定理二 && int---32bits;*/

return ~(1 << 31);

}

/*

* bitXor - x^y using only ~ and &

* Example: bitXor(4, 5) = 1

* Legal ops: ~ &

* Max ops: 14

* Rating: 2

*/

int bitXor(int x, int y) {

/*或非定义:p ⊕ q ↔ (﹁p ∧ q) ∨ (p ∧ ﹁q)*/

return (x&~y) | (~x&y);

}

/*

* getByte - Extract byte n from word x

* Bytes numbered from 0 (LSB) to 3 (MSB)

* Examples: getByte(0x12345678,1) = 0x56

* Legal ops: ! ~ & ^ | + << >>

* Max ops: 6

* Rating: 2

* more explain:

* LSB(Least Significant Bit)是“最低有效位”,MSB(Most ~ Bit)是“最高有效位”.

* 因此,这个函数想要表达的意思就是说:n的值从0到3,

* 且0代表最低有效位(可以理解为排在最右边的那个字节,也就是0x78),

* 3代表最高有效位(可以理解为排在最左边的那个字节,也就是0x12),同理:1代表的就是0x56.

*/

int getByte(int x, int n) {

/*right shift: offset is n*8(n<<3); get the right byte*/

x >>= (n << 3);

return x & 0x000000ff;

}

/*

* isEqual - return 1 if x == y, and 0 otherwise

* Examples: isEqual(5,5) = 1, isEqual(4,5) = 0

* Legal ops: ! ~ & ^ | + << >>

* Max ops: 5

* Rating: 2

*/

int isEqual(int x, int y) {

/*!:将0变为1,非0变为1(ATTENTION:是非0不是只有1,不是指局部的位,是整体)*/

return !(x^y);

}

/*

* negate - return -x

* Example: negate(1) = -1.

* Legal ops: ! ~ & ^ | + << >>

* Max ops: 5

* Rating: 2

*/

int negate(int x) {

/*补码中的“相反数”:在补码中有这样一个定理,对于数x来说,-x = ~x + 1.*/

return ~x + 1;

}

/*

* isPositive - return 1 if x > 0, return 0 otherwise

* Example: isPositive(-1) = 0.

* Legal ops: ! ~ & ^ | + << >>

* Max ops: 8

* Rating: 3

*/

int isPositive(int x) {

/*ATTENTION:注意(!!x)的巧用:判断x本身是否为0*/

return (!((x >> 31) & 1))&(!!x);

}

2019-9-10

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值