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

前端 未结 5 1474
有刺的猬
有刺的猬 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∈
    }
    

提交回复
热议问题