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 + hash
和hash * 32 + hash
是一样的,但是怎么变成hash * 33
是我不明白的。
我试图推断 hash * 32
溢出并换行成为模 2^n 操作,但显然这不是因为 a) hash
是 ulong
类型
足以容纳 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
这是基础数学,但也许您累了或工作过度了,只是看不出它是如何工作的:)
在我正在看的一本书中,有一个散列函数如下所示
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 ashash * 32 + hash
or justhash * 33
.
我明白为什么hash << 5 + hash
和hash * 32 + hash
是一样的,但是怎么变成hash * 33
是我不明白的。
我试图推断 hash * 32
溢出并换行成为模 2^n 操作,但显然这不是因为 a) hash
是 ulong
类型
足以容纳 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
这是基础数学,但也许您累了或工作过度了,只是看不出它是如何工作的:)