Unsigned / Signed Arithmetic Problems from A Programmer's Perspective Textbook

随声附和 提交于 2019-12-09 01:57:37

问题


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

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

For each of the following C expressions, you are to indicate whether or not the expression always yields 1. If it always yields 1, describe the underlying mathematical principles. Otherwise, give an example of arguments that make it yield 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

For these questions, I got that only A could yield 0 while the rest always yielded 1.

I know this is probably wrong and I'm not looking for direct answers but I was hoping to get some general knowledge / advice on how to approach these problems.

I have a really bad professor and I've been trying to find resources online but I don't really know where to start or what to look for. I know the basics of unsigned / two's complement arithmetic and bit-shifting but I don't know how to apply it to find counter cases for these problems.


回答1:


The C programming language does not specify the result of an overflow of integral signed quantities; neither it defines x << n if x is signed and negative.

However, it is not uncommon that arithmetic operations are performed regardless of the sign, considering both signed and unsigned n-bit integers to be numbers modulo 2^n represented in the two's complement system.

This must be assumed for your exercise, which is almost meaningless otherwise.

Example for 8-bit integers:

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

in binary representation:

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

Between signed and unsigned, only the representative system of the integers modulo 2^n differ, which is relevant for printing, but not for internal computations (as long as only +, -, * and bitwise operations are used).

For signed integers, exactly the negative integers have the first bit set to 1. Casts between signed and unsigned are irrelevant except for printing.

I insist, this is assumed for your exercises, but the C programming language does not specifies most of my claims.

A. (x<y) == (-x>-y)

Is disproved by x == INT_MIN, y == INT_MIN + 1, because INT_MIN == -INT_MIN.

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

True:

   ((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)

True:

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: the cast from signed to unsigned is assumed not to change the internal representation, and operators are assumed to ignore the signedness of integers. In other words, x-y == -(y-x) holds wherever casts are put.

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

True:

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

Examples with signed 32-bit integers:

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


来源:https://stackoverflow.com/questions/29572107/unsigned-signed-arithmetic-problems-from-a-programmers-perspective-textbook

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!