You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

关于DDIA中Thrift CompactProtocol int64变长编码的疑问

Thrift CompactProtocol int64 变长编码逻辑解析

首先明确Thrift CompactProtocol对有符号整数(如int64)的编码分为两步:ZigZag编码 + 变长字节编码。

1. ZigZag编码(处理有符号数)

目的是将负数映射为正奇数,正数映射为正偶数,让绝对值小的数(含负数)能用更少字节存储:

  • 编码公式:encoded = (value << 1) ^ (value >> 63)
    • 正数右移63位结果为0,所以正数编码后是value * 2
    • 负数右移63位结果为全1(补码特性),异或后等价于-(value * 2 + 1)
  • 解码公式:value = (encoded >> 1) ^ -(encoded & 1)

2. 变长字节编码(处理无符号编码值)

将ZigZag后的无符号数拆分为7位一组,从最低位开始编码:

  • 每次取当前数的最低7位作为字节的低7位
  • 字节最高位设为1表示后续还有更多字节,设为0表示这是最后一个字节
  • 按「低位组在前,高位组在后」的顺序写入字节,直到原数右移7位后为0

针对1337的正确编码过程

1337是正数,ZigZag编码后为 1337 * 2 = 2674(二进制:101001110010)
对2674进行变长编码:

  • 第一步:取最低7位1110010(十进制114),2674右移7位得20(非0),所以第一个字节为 1110010 | 0x80 = 0xF2(二进制11110010,最高位为1)
  • 第二步:处理20,取最低7位0010100(十进制20),20右移7位得0,所以第二个字节为 00010100(二进制00010100,最高位为0)

最终编码结果为两个字节:0xF2(11110010)和0x14(00010100),对应你看到的「1|1110010 0|0010100」(可能示例排版时少写了一个0)。

关于你提到的注释矛盾

你提到的「111011对应37、0010100对应13」明显不符合编码逻辑:

  • 111011是十进制59,不是37;0010100是十进制20,不是13
  • 而你认为的100101(37)和1101(13),组合后是37 + 13*128 = 1701,对应ZigZag解码后的原数是-851,和1337完全无关

这大概率是DDIA示例的排版或注释笔误,实际编码逻辑以上述步骤为准。

内容的提问来源于stack exchange,提问作者EugeneH

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 17:26:03