How to convert from sign-magnitude to two's complement

前端 未结 5 1420
有刺的猬
有刺的猬 2021-01-24 06:39

How would I convert from sign-magnitude to two\'s complement. I don\'t know where to start. Any help would be appreciated. I can only use the following operations:!,~,|,&,^,

相关标签:
5条回答
  • 2021-01-24 06:57

    Interestingly, the conversion between the two formats is symmetrical, so you need only one conversion function to swap from one format to the other. Here is the complete conversion without relying on any conditionals:

    uint32_t convertSignRepresentation(uint32_t in) {
        uint32_t mask = -(in >> 31);
        return mask&0x80000000-in | ~mask∈
    }
    

    The technique I used here is essentially replacing the conditional operator in

    uint32_t convertSignRepresentation(uint32_t in) {
        return (in >> 31) ? 0x80000000-in : in;
    }
    

    by a bitmask of only zeros or ones to select the correct resulting value.


    Please note, that 0x80000000 (either smallest possible value, or negative zero) is projected to positive zero, and cannot be recovered. So convertSignRepresentation(converSignRepresentation(0x80000000)) yields zero instead of 0x80000000. This might give nasty surprises. It might be avoided in theory by mapping 0x80000000 onto itself, but that is not as easy to do and has even nastier surprises...


    Edit:
    A comment pointed out that subtraction was not on the list of allowed operators, even though addition is. I don't know whether this was deliberate or a mistake. Anyways, the operation -x can be written as ~x + 1. With this, the code becomes:

    uint32_t convertSignRepresentation(uint32_t in) {
        uint32_t mask = ~(in >> 31) + 1;
        return mask&0x80000001+~in | ~mask∈
    }
    
    0 讨论(0)
  • 2021-01-24 07:06

    Signed Numbers are 8 bit quantities with the least significant 7 bits representing the magnitude and the most significant bit indicating the sign. 0 in this bit indicates the number is positive, and 1 indicates it is negative. There is no magnitude information in this 8th bit-just the sign.

    To convert a negative signed number to two's complement, first set the 8th bit to zero. Then invert all 8 bits. Finally add 1. An example follows:

    Signed Number:

    10001111

    set the 8th bit to zero: (use & operator)

    00001111

    invert all 8 bits: (use bitwise-complement operator)

    11110000

    finally, add 1; resulting in the final two's complement number: (use + operator)

    11110001

    If the 8th bit is 0, indicating that the signed number is positive, the number requires no conversion. It's two's complement representation is the same as the signed magnitude representation.

    0 讨论(0)
  • 2021-01-24 07:08

    You can convert signed-magnitude to two's complement by subtracting the number from 0x80000000 if the number is negative. This will work for a 32-bit integer on a machine using two's complement to represent negative values, but if the value is positive this will result in a two's complement negation. A right shift of a two's complement negative number will shift in one's, we can utilize this to make a mask to select between the original value, or the conversion of a signed-magnitude negative value to a two's complement negative value.

    int sm2tc(int x) {
      int m = x >> 31;
      return (~m & x) | (((x & 0x80000000) - x) & m);
    }
    
    0 讨论(0)
  • 2021-01-24 07:09

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

    1) On a two's complement machine.
    2) Use only !,~,|,&,^,+,>>,<<
    3) Does not use ?:, -, *, /
    4) Does not assume 4-byte int
    5) Work with all Sign Magnitude 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));
    }
    
    0 讨论(0)
  • 2021-01-24 07:18

    There you go.

    uint32_t sm2tc(uint32_t x)
    {
            return (x & 0x80000000)
                    ? ((~(x & 0x7fffffff)) + (uint32_t)1)
                    : x;
    }
    
    0 讨论(0)
提交回复
热议问题