Solidity
如何將預設的二進制補碼表示形式轉換為符號幅度形式?
根據這個答案,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
為更大的整數類型調整這個非常簡單;相應地更改變數類型並更新遮罩,因此
int16
將mask
是2**15 - 1
.