int x = random();
int y = random();

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

对于以下每一个C表达式,您将指示
不是表达式总是得到1。如果它总是得到1,请描述基本的数学原理。否则,给出一个使其产生0的参数示例。
A. (x<y) == (-x>-y)
B. ((x+y)<<4) + y-x == 17*y+15*x
C. ~x+~y+1 == ~(x+y)
D. (ux-uy) == -(unsigned)(y-x)
E. ((x >> 2) << 2) <= x

对于这些问题,我得到只有A可以产生0,而其余的总是产生1。
我知道这可能是错误的,我不想寻找直接的答案,但我希望得到一些关于如何解决这些问题的一般知识/建议。
我有一个很差劲的教授,我一直试图在网上找到资源,但我真的不知道从哪里开始或找什么。我知道unsigned/two的补码算法和位移位的基本原理,但我不知道如何应用它来寻找这些问题的反例。

最佳答案

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不同,这与打印有关,但与内部无关
计算(只要使用+-*和按位运算)。
对于有符号整数,正是负整数的第一位设置为
一。除了打印之外,有符号和无符号之间的强制转换是不相关的。
我坚持认为,这是你的练习,但C编程语言
并没有详细说明我的大部分主张。
A.(x<y) == (-x>-y)
x == INT_MINy == INT_MIN + 1反驳,
因为INT_MIN == -INT_MIN
B.((x+y)<<4) + y-x == 17*y+15*x
正确:
   ((x+y) << 4     ) + y-x
== ((x+y) * 0x10000) + y-x
== ((x+y) * 16     ) + y-x
== 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)(y-x)
True:假定从有符号到无符号的转换不会更改内部
假设表示和运算符忽略
整数。换言之,x-y == -(y-x)在放置强制类型转换的任何位置都有效。
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

10-07 19:40
查看更多