代码之家  ›  专栏  ›  技术社区  ›  Finlay Weber

为什么在执行位操作时,填充会向左添加零,而左对齐会向右添加零?

  •  0
  • Finlay Weber  · 技术社区  · 2 年前

    我不确定这是一个一般的比特操作相关问题还是以太坊特有的问题。但我正在阅读以太坊规范的一部分 here 并且我被比特相关的操作弄糊涂了。

    例如,在 Example 第a节uint32值为 69 填充到 32 字节变为 0x0000000000000000000000000000000000000000000000000000000000000045 .

    我理解这一点。转动 69 到十六进制,即 45 然后用30个零填充它。

    但是一个值“abc”之后 左对齐 成为 0x6162630000000000000000000000000000000000000000000000000000000000

    现在我很困惑。

    为什么这里的零加在右边?我理解0x616263的来源,它是“abc”的十六进制表示。但是当填充的十六进制表示时 69 上面,零被添加在左边,但使用“abc”,零被增加在右边。为什么会出现这种情况?

    0 回复  |  直到 2 年前
        1
  •  0
  •   tenbits    2 年前

    两者都是big-endian。在EVM中,存储器在32字节块/缓冲器中进行处理。因此,即使您的数据类型是 uint8 uint32 它仍然被管理为 uint256 价值观 占用32字节 ).

    0x0000000000000000000000000000000000000000000000000000000000000045 == 69n
    0x4500000000000000000000000000000000000000000000000000000000000000 == 31209586552245380797759367053122912663576675554410933276260051939632835723264n
    

    这就是整数的存储方式,即使字节中的位也固定在右边:

    00000011 === 3
    

    Strings 是从左到右的简单内存缓冲区。有一些与EVM相关的事情需要记住——就像所有事情一样 strings 也被保存到32字节的块中。因此,如果字符串的长度只有5个字节,那么之后会得到零。如果长度较大,那么在第一个块中,您只获得字符串值的长度(也可以根据长度进行右锚定 uint256 ),之后的块保持实际的字符串数据。

    大/小端序不仅与数据的锚有关,还与字节顺序有关:

    // 0x3045
    // big-endian byte order
    30 45
    // little endian byte order
    45 30