1

I am trying to encode 3 signed integers into 3 - 32 bits slots using bit shifting, which works fine but not with negative numbers. This could be a simple problem in C++ with the negative conversion but I never work on C++ or know any good resources to follow.

Could anyone please shed light of how to deal with a negative number in this situation?

Really appreciate it.

    function encodeNumbers(int256 a, int256 b, int256 c) public pure returns(uint256 encoded) {

        encoded |= uint(a) << 64;

        encoded |= uint(b) << 32;

        encoded |= uint(c);

        return encoded;
    }
    
    function decodeNumber(uint256 encoded) public pure returns (int256 a, int256 b, int256 c) {

        a = int(encoded) >> 64;

        b = (int(encoded) << 192) >> 224;

        c = (int(encoded) << 224) >> 224;
    } 
1
  • 1
    The problem you have is that negative numbers intXX have their sign extended to the full bit length. If you want to combine several of them you have to mask out those bits.
    – Ismael
    Aug 28, 2021 at 20:55

1 Answer 1

0

You could use casting to/from uint32/int32 to cut the unneeded bits.

// SPDX-License-Identifier: MIT

pragma solidity >=0.7.0 < 0.9.0;

contract Untitled {
    
    event Numbers(int256 i, int256 j, int256 k);
    
    function foo() public returns (uint256) {
        int256 x = -123;
        int256 y = 8545;
        int256 z = -42;
        
        uint256 encoded = encodeNumbers(x, y, z);
        (int256 r, int256 s, int256 t) = decodeNumber(encoded);
        emit Numbers(r, s, t);
        
        return encoded;
    }
    
    function encodeNumbers(int256 a, int256 b, int256 c) public pure returns(uint256 encoded) {
        encoded |= uint256(uint32(int32(a))) << 64;
        encoded |= uint256(uint32(int32(b))) << 32;
        encoded |= uint256(uint32(int32(c)));

        return encoded;
    }
    
    function decodeNumber(uint256 encoded) public pure returns (int256 a, int256 b, int256 c) {
        a = int256(int32(uint32(encoded >> 64)));
        b = int256(int32(uint32(encoded >> 32)));
        c = int256(int32(uint32(encoded)));
    } 
    
}
1
  • Hi Ismael, thank you so much for your input. It's a decent solution. Aug 29, 2021 at 4:14

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.