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

时间:2015-04-10 23:18:38

标签: c bit-manipulation unsigned twos-complement

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.

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

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

1 个答案:

答案 0 :(得分:2)

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

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

对于有符号整数,正整数的第一位设置为 1.除了打印之外,签名和未签名之间的转换是无关紧要的。

我坚持认为,这是假设你的练习,而是C编程语言 并没有详细说明我的主张。

一个。 (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

℃。 ~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)可以保存任何演员阵容。

电子。 ((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