有人可以解释这个按位数组环绕表达式吗?

Can someone explain this bitwise array-wrap-around expression?

我一直在研究 Diamond-square 算法,我遇到了 this website,它向我指出了 Notch 的 Minicraft 的源代码,并对 Notch 实现的算法进行了转换。

在大多数情况下,我理解该算法,但我可以理解这两个函数中的特定表达式:

private double sample(int x, int y) {
    return values[ (x & (w - 1)) + (y & (h - 1)) * w ];
}

private void setSample(int x, int y, double value) {
    values[ (x & (w - 1)) + (y & (h - 1)) * w ] = value;
}

我确实理解 x + y * w,但不理解 (x & (w - 1)) + (y & (h - 1)) * w,这篇文章除了说明它用于环绕之外没有解释这一点。

我在 python 中编码,但我认为 Java 的按位 & 和 python 之间没有任何区别,所以我摆弄了一下,但我仍然无法理解。我做的其中一件事是模拟不同的 xy 值并将它们提供给该计算的循环:

import random
w = h = 257     # 2^8 + 1
for i in xrange(10):
    x = int(random.uniform(0, 1) *255)
    y = int(random.uniform(0, 1) *255)

    print x, y, '|', (x & (w-1)) + (y & (h-1)) *w

    # I used a less readable right-aligning version of the above to display the output:
    # print str( x ).rjust(3), str( y ).rjust(3), '|', str( (x & (w-1)) + (y & (h-1)) * w ).rjust(3)

输出:

112 213 |   0
181 117 |   0
  1 105 |   0
216 223 |   0
170 185 |   0
158  32 |   0
124 225 |   0
 62 153 |   0
 90 147 |   0
196  69 |   0

除非我在这里做一些根本性的错误,否则它总是给我零,除非 x and/or y 等于 w-1,在这种情况下:

256  15 |   256
 21 256 | 65792
256 256 | 66048

在实际算法中,xy 的值似乎总是(如果我理解正确的话)介于 0halfStep 之间,其中 halfStep = stepSize/2stepSize = featureSise 似乎(在 Minicraft 的代码中)总是硬编码为 1632。因此,根据我目前的理解,表达式的计算结果总是 0.

所以我很困惑。我不知道这有什么用,也不知道它在实践中是如何工作的……我知道它有效,但它看起来像魔法…… 我了解按位 & 的工作原理,但这似乎没有帮助。

wh 必须是 2 的幂(分别表示 xy 的局部边界)。 然后,w-1h-1 是 1 的序列。一个代表可能导致值分别低于 wh(并且仍然是 >= 0)的每一位信息。

当您现在评估按位 (&) 时,例如x & (w-1),这实际上会产生 x % w,其中 % 是 python 中的 modulo 操作,用于 x >= 0。 因此,如果 w > x >= 0x 映射到 x,否则 x 被截断(将较高位清零),从而满足 w > x >= 0。 这同样适用于 yh.

因此,这些逻辑运算无非是mod的比特级计算。

对于您的代码:设置 w=h=256 一切都会成功。