程序员视角教科书中的无符号/有符号算术问题

int x = random(); int y = random(); unsigned ux = (unsigned) x; unsigned uy = (unsigned) y; 

对于以下每个C表达式,您要指出表达式是否总是产生1.如果它总是得到1,则描述基础数学原理。 否则,举一个让它产生0的参数的例子。

 A. (x-y) B. ((x+y)<> 2) << 2) <= x 

对于这些问题,我认为只有A可以产生0,而其余的总是产生1。

我知道这可能是错的,我不是在寻找直接的答案,但我希望得到一些关于如何处理这些问题的一般知识/建议。

我有一个非常糟糕的教授,我一直在努力寻找在线资源,但我真的不知道从哪里开始或寻找什么。 我知道无符号/二进制补码算术和位移的基础知识,但我不知道如何应用它来查找这些问题的计数器情况。

C编程语言没有指定积分有符号数量溢出的结果; 它既没有定义x << n如果x是有符号的,也是负数。

然而,考虑到有符号和无符号的n位整数都是在二进制补码系统中表示的模2 ^ n,不管符号如何都执行算术运算并不罕见。

这必须假设你的运动,否则几乎毫无意义。

8位整数的示例:

 unsigned domain: (0..127), ( 128..255) signed domain: (0..127), (-128..-1) 

在二进制表示:

 unsigned domain: 00000000..01111111 and 10000000..11111111 signed domain: 00000000..01111111 and 10000000..11111111 

在有符号和无符号之间,只有模2 ^ n的整数的代表系统不同,这与打印有关,但不与内部计算有关(只要使用+-*和按位运算)。

对于有符号整数,正整数将第一位设置为1.有符号和无符号之间的转换与打印无关。

我坚持认为,这是为你的练习所假设的,但是C编程语言没有规定我的大部分主张。

A. (x-y)

x == INT_MINy == INT_MIN + 1反驳,因为INT_MIN == -INT_MIN

B. ((x+y)<<4) + yx == 17*y+15*x

真正:

  ((x+y) << 4 ) + yx == ((x+y) * 0x10000) + yx == ((x+y) * 16 ) + yx == 17 * y + 15 * x 

C. ~x+~y+1 == ~(x+y)

真正:

 x + ~x + 1 == 0 ~x + 1 == -x ~(x+y) + 1 == -(x+y) ~(x+y) + 1 == -x + -y ~(x+y) + 1 == ~x + 1 + ~y + 1 ~(x+y) == ~x + ~y + 1 

D. ((unsigned)x-(unsigned)y) == -(unsigned)(yx)

True:假定从有符号到无符号的转换不会更改内部表示,并假定运算符忽略整数的有符号。 换句话说, xy == -(yx)保存任何演员阵容。

E. ((x >> 2) << 2) <= x

真正:

  x == (x >> 2) << 2 + two_last_significant_bits_of_x == (x >> 2) << 2 + positive >= (x >> 2) << 2 

带符号的32位整数的示例:

 x == 5 x == 00000000000000000000000000000101 in base2 x >> 2 == 00000000000000000000000000000001 in base2 (x >> 2) << 2 == 00000000000000000000000000000100 in base2 (x >> 2) << 2 == 4 x == -5 x == 11111111111111111111111111111011 in base2 x >> 2 == 11111111111111111111111111111110 in base2 (x >> 2) << 2 == 11111111111111111111111111111000 in base2 (x >> 2) << 2 == -8