比特币Merkle树CalcTreeWidth函数位运算计算原理问询
比特币Merkle树
CalcTreeWidth函数位运算逻辑解析 这个函数的核心是用位运算实现了整数除法的向上取整,刚好匹配Merkle树的层级节点数计算规则。
先明确Merkle树的节点数计算规则
比特币的Merkle树是二叉哈希树,层级节点数遵循两个规则:
- height=0 是最底层的叶子节点层,节点数等于交易总数
nTransactions - 每往上一层,每2个相邻节点拼接计算出1个父节点;如果当前层节点数是奇数,最后一个节点会被复制一份凑成偶数个再计算,因此上一层的节点数永远是「当前层节点数除以2,向上取整」。
递推后可以得到结论:高度为height的层级,节点总数等于把nTransactions连续做height次除以2向上取整,最终结果等价于数学上的向上取整除法:ceil(nTransactions / 2^height)。
位运算的实现原理
你看到的位运算组合,本质是无符号整数场景下计算「除以2的整数次幂时向上取整」的经典优化写法,拆解如下:
对无符号整数做右移
>> height操作,等价于除以2^height后向下取整,也就是普通整数除法的截断效果。整数运算中,实现「a除以k向上取整」有通用公式:
向上取整(a/k) = 向下取整( (a + k -1)/k )
这个公式的逻辑很直白:如果a不能被k整除,加k-1之后必然会产生1次跨过k整数倍的进位,后续做向下取整除法时就会多算1,刚好补上向上取整的差值;如果a刚好能被k整除,加k-1不会达到下一个k的整数倍,结果和直接做除法一致。
代入到这个函数的场景里,k就是
2^height,对应位运算写法就是1 << height,k-1就是你观察到的(1 << height) -1(低height位全1的值)。把值套进通用公式,就得到了代码里的写法:(nTransactions + (1 << height) -1) >> height
实际演算例子
假设总交易数nTransactions=5:
- height=0(叶子层):k=1,计算得(5+0)>>0=5,和实际叶子节点数一致
- height=1(叶子上一层):k=2,计算得(5+1)>>1=3,对应5个叶子凑出3个父节点,符合奇数节点复制的规则
- height=2:k=4,计算得(5+3)>>2=2,对应3个节点再往上凑出2个节点
- height=3:k=8,计算得(5+7)>>3=1,到达根节点层,节点数为1,结果完全正确。
内容的提问来源于stack exchange,提问作者Morty
相关产品推荐
相关产品推荐

