1

According to this answer the EVM by default uses two's complement notation for handling signed integers. However for my application I would like to work with the sign-magnitude representation where the sign can either be 0 or 1 corresponding to + or - respectively and the remaining bits comprise the magnitude. For example, if a int8 variable has a value of +1 it would be represented in binary as 0000_0001 and if it has a value of -1 it would 1000_0001 in sign-magnitude notation.

However since the EVM uses two's complement I first have to convert it into sign-magnitude representation before I can work with it. How exactly would I do this in a gas-efficient manner?

function twos_comp_to_sign_mag(int8) returns(int8);

// 255 in binary is 1111_1111 or -1 in two's complement notation
// 129 in binary is 1000_0001 or -1 in sign-magnitude notation
twos_comp_to_sign_mag(255) == 129

1 Answer 1

1

I asked basically the same question on StackOverflow but for python, below is my solidity adaptation using this answer:

// SPDX-License-Identifier: GPL-3.0
contract TwosComplement {

    function twos_comp_to_sign_mag(int8 value) external pure returns(int8) {
        
        int8 mask = 2**7 - 1; // 0111_1111

        if (value < 0) {
            value = -(value & mask);
        }
        return (-1 & value) | (value & mask);        
    }
}

where the following holds true:

twos_comp_to_sign_mag(positiveInt) == positiveInt;
// e.g.: twos_comp(0) == 0

twos_comp_to_sign_mag(negativeInt) == -128 - negativeInt;
// ex1: twos_comp(-1) == -128 - (-1) = -128 + 1 = -127
// ex2: twos_comp(-127) == -128 - (-127) = -128 + 127 = -1
// ex3: twos_comp(-128) == -128 - (-128) = -128 + 128 = 0

To adjust this for larger integer types is really simple; change the variable types accordingly and update the mask, so for int16 the mask will be 2**15 - 1.

2
  • What does the & do over here? I used to think that they are only for logical AND operations for comparisons and such.
    – Ishan
    Sep 24, 2023 at 22:49
  • @Ishan & is a bitwise AND, you can read up on it, but in essence it compares each bit in the value to the corresponding bit in the mask and if both are 1 then the value at that bit in the result is 1 else it's 0
    – MShakeG
    Sep 25, 2023 at 7:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.