Search code examples
cpuzzlebitlimits

In binary, convert from signed-magnitude to two’s-complement. All in C


I have an interesting puzzle. I need to convert from a signed number, say -5 (0x80000005) to two’s complement -5 (0xFFFFFFFB). The only operators I can use are, !, ~, &, ^, |, +, <<, >> and at most 15 of them in any combination with as many variables as I want. = may be used and does not count towards the total number of operators. Also, no “if” statements, loops or calls to functions of any kind may be used.

the function will look like

int sign2two(int x){
//... some stuff here
return x;
}

The problem I am having is that I can find out if the number is negative. But I want to say, if num is negative then flip bits and add 1. Otherwise return number. And I can’t figure out how to do that. Thanks.


Solution

  • To convert from Sign Magnitude x to Two's Complement y:

    1) On a two's complement machine.
    2) Uses only !, ~, &, ^, |, +, <<, >>
    3) Does not use ?:, -, *, /
    4) Does not assume 4-byte int
    5) Works with all Sign Magnitude integers including +0 and -0

    #include <limits.h>
    int sm2tc(int x) {
      int sign = x & INT_MIN;
      int negmask = UINT_MAX + !sign;
      return (x & ~negmask) | (negmask & ((~x + 1)^INT_MIN));
    }
    

    This answer is to a duplicate question How to convert from sign-magnitude to two's complement whose selected answer did not meet the OP's stated criteria considering operation restriction.