Solidity
如何將兩個 int16 打包成一個 byte32?
我有一個使用笛卡爾座標的契約。我最初的想法是將單個位置(x,y)映射到值/結構。我想用一個
byte32
可以轉換回座標的座標來定義任何給定的座標對。前任:int16 x, int16 y; byte32 key = coordinatesToBytes32(x, y);
反之亦然:
[x, y] = bytes32ToCoordinates(key);
進入之後,
solc@^0.5.0
我發現您無法再在這些類型之間進行顯式轉換,這使我難以進行強制轉換、屏蔽、移位和執行按位運算。作為參考,這是我做的地方(注意solidity版本):pragma solidity ^0.4.17; contract CoordinateUtils { function coordinatesToBytes32(int16 x, int16 y) internal pure returns(bytes32) { return (bytes32(x) << 16 & 0xFFFFFFFF) | bytes16(y); // left shift extends negative so we mask out } function bytes32ToCoordinates(bytes32 b) internal pure returns(int16 x, int16 y) { return (int16(b >> 16), int16(b)); } }
此外,如果這看起來效率低下,我願意接受有關儲存笛卡爾相關值的其他建議。
首先,
int16
它只有 2 個字節寬(16 位),而不是 16 個字節。你的意思是int128
?其次,您仍然可以在 Solidity 0.5.x 中將兩個
int16
值打包/解包為單個值,您只需要更多的類型轉換:bytes32
function pack (int16 a, int16 b) public pure returns (bytes32) { return bytes32 (bytes2 (a)) >> 16 | bytes2 (b); } function unpack (bytes32 x) public pure returns (int16, int16) { return (int16 (bytes2 (x << 16)), int16 (bytes2 (x))); }
注意,轉向的方向。這是因為,
bytesN
擴展的工作方式與數字不同:bytes2 a = 0x0102; bytes4 b = bytes32 (a); // 0x01020000 (padded from right) int16 c = 0x0102; int32 d = int32 (c); // 0x00000102 (padded from left)