Solidity

如何將預設的二進制補碼表示形式轉換為符號幅度形式?

  • January 23, 2022

根據這個答案,EVM 預設使用二進制補碼表示法來處理有符號整數。但是,對於我的應用程序,我想使用符號幅度表示 ,其中符號可以是 0 或 1,分別對應於 + 或 - ,其餘位構成幅度。例如,如果一個int8變數有一個值,+1它將以二進製表示0000_0001,如果它有一個值,-1它將1000_0001以符號大小表示法。

然而,由於 EVM 使用二進制補碼,我首先必須將其轉換為符號幅度表示,然後才能使用它。我將如何以省油的方式做到這一點?

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

我在 StackOverflow 上問了基本相同的問題,但對於 python,下面是我使用這個答案的可靠性改編:

// 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);        
   }
}

以下情況成立:

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

為更大的整數類型調整這個非常簡單;相應地更改變數類型並更新遮罩,因此int16mask2**15 - 1.

引用自:https://ethereum.stackexchange.com/questions/119678