C 对移位操作感到困惑

C confused about bitwise shift operation

在我正在看的一本书中,有一个散列函数如下所示

static inline ulong zend_inline_hash_func(const char *arKey, uint nKeyLength)
{
    register ulong hash = 5381;

    for (uint i = 0; i < nKeyLength; ++i) {
        hash = ((hash << 5) + hash) + arKey[i];
    }
    return hash;
}

The hash << 5 + hash expression is the same as hash * 32 + hash or just hash * 33.

我明白为什么hash << 5 + hashhash * 32 + hash是一样的,但是怎么变成hash * 33是我不明白的。 我试图推断 hash * 32 溢出并换行成为模 2^n 操作,但显然这不是因为 a) hashulong 类型 足以容纳 hash *32 表达式的结果。 b) 即使 unint 仍然大到被相关乘法溢出 有更多 C 知识的人可以通过简单的解释帮助我,甚至可以指出我困惑的根源。 谢谢你。

这与 C 语言关系不大,与数学关系较大。

The hash << 5 + hash expression is the same as hash * 32 + hash or just hash * 33.

基本代数表明这些都是真的(这些是用 C 语言编写的):

/* #1 */ (a * b + a * c) == (a * (b + c))
/* #2 */ (a) == (a * 1)

应用#2,我们可以说:

(hash * 32 + hash) == (hash * 32 + hash * 1)

现在应用#1,我们可以发现:

(hash * 32 + hash * 1) == (hash * (32 + 1))

这可以简化为:

hash * 33

这是基础数学,但也许您累了或工作过度了,只是看不出它是如何工作的:)