0

我需要仅使用运算符将​​二进制补码转换为 C 中的符号幅度

! ~ & ^ | + << >>

我的方法是找到标志: int sign = !(!(a>>31));

基本上,if sign == 1. 我想翻转数字并加1,否则只想显示数字。

问题是我不能使用任何循环、if 语句等。这就是我正在做的事情:

int s_M = ((((a+1)>>31)^sign)+1)&sign;

有什么建议么?

4

4 回答 4

2

来自http://graphics.stanford.edu/~seander/bithacks.html#IntegerAbs

int const mask = v >> 31;
unsigned int r = (v + mask) ^ mask;

给出绝对值(大小)。如果您想添加符号位,只需掩码和/或第 32 位:

unsigned int s_M = r | (v & 0x80000000);

或者,如果您正在寻找单线:

unsigned int s_M = ((v + (v >> 31)) ^ (v >> 31)) | (v & 0x80000000);
于 2013-10-30T19:14:32.260 回答
0

要获得最后一位,您可以使用掩码操作

   int last_bit = 32 bit integer & 0x80000000 
   o/p  may be 0 or 0x80000000    

如果它0只是显示给定的数字,否则您必须执行以下操作以表示有符号的幅度

1)从数字中减去 1

2)对结果执行1s补码(即否定~

3)设置结果数的最后一位

 I mean  ( ~ (num -`1) ) | 0x7fffffff 

因为您限制不使用-运算符。执行2's complement on -1并将其添加到num.

To put it simple in one line
 num & 0x80000000 ? printf("%d",(~(num+((~1)+1))) | 0x7fffffff) : printf("%d",num)   ;
于 2013-10-30T18:05:36.260 回答
0

我不完全确定输出应该是什么,但是要获得幅度,您可以执行以下操作:

int m = (a^(a>>31)) + sign;

基本上,将一个负数向右移动 31 位将使其全为 1,或0xffffffff,然后您可以使用它对输入数进行异或并使其为正数。正如您正确指出的那样sign,在这种情况下需要添加正确的结果。

如果输入数字一开始是正数,则移位结果为零,因此 xor 什么也不做。在这种情况下添加sign也不会做任何事情,因此它会导致输入数字。

于 2013-10-30T17:54:21.837 回答
0

当你2 补码转换时,你应该减去 1,而不是加。

于 2013-10-30T17:50:12.780 回答