Convert two's complement to sign-magnitude

无人久伴 提交于 2019-11-29 18:06:18

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

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

Gives the absolute value (magnitude). If you wish to add the sign bit back simply mask and or the 32nd bit:

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

Or if you're looking for a one liner:

unsigned int s_M = ((v + (v >> 31)) ^ (v >> 31)) | (v & 0x80000000);

When you're converting from 2 complement, you should subtract 1, not add.

I'm not entirely sure what the output should be, but to obtain the magnitude you can do something like this:

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

Basically, shifting a negative number 31 bits to the right will make it all 1's, or 0xffffffff, which you can then use to xor the input number and make it positive. As you correctly noted sign needs to be added then for the correct result in that case.

If the input number was positive to begin with, the shift results in a zero and so the xor does nothing. Adding sign in that case also doesn't do anything, so it results in the input number.

To get the last bit you could use mask operation

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

if it is 0 just display the given number else you have to perform the following operations to represent in signed magnitude

1) Subtract 1 from the number

2) perform 1s complement on the resultant ( that is negation ~)

3) Set the last bit of the resultant number

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

since your restricted not to use - operator. Perform the 2's complement on -1 and add it to the num.

To put it simple in one line
 num & 0x80000000 ? printf("%d",(~(num+((~1)+1))) | 0x7fffffff) : printf("%d",num)   ;
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!