Convert two's complement to sign-magnitude

↘锁芯ラ 提交于 2019-12-18 09:44:30

问题


I need to convert from two's complement to sign-magnitude in C using only the operators

! ~ & ^ | + << >>

My approach is to find sign: int sign = !(!(a>>31));

basically, if sign == 1 . I want to flip the number and add 1 else just want to display the number.

The thing is I can't use any loops, if statements etc. This is what I'm working on:

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

any suggestions?


回答1:


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



回答2:


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




回答3:


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.




回答4:


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


来源:https://stackoverflow.com/questions/19689586/convert-twos-complement-to-sign-magnitude

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