diff --git a/numerics/hilbert/hilbert.go b/numerics/hilbert/hilbert.go index a84c707..647d28f 100644 --- a/numerics/hilbert/hilbert.go +++ b/numerics/hilbert/hilbert.go @@ -26,8 +26,8 @@ This expects coordinates in the range [0, 0] to [MaxInt32, MaxInt32]. Using negative values for x and y will have undefinied behavior. Benchmarks: -BenchmarkEncode-8 10000000 181 ns/op -BenchmarkDecode-8 10000000 191 ns/op +BenchmarkEncode-10 23791095 50.66 ns/op +BenchmarkDecode-10 32430058 36.99 ns/op */ package hilbert @@ -44,17 +44,16 @@ func boolToInt(value bool) int32 { return int32(0) } -func rotate(n, rx, ry int32, x, y *int32) { +func rotate(n, rx, ry int32, x, y int32) (int32, int32) { if ry == 0 { if rx == 1 { - *x = n - 1 - *x - *y = n - 1 - *y + x = n - 1 - x + y = n - 1 - y } - t := *x - *x = *y - *y = t + x, y = y, x } + return x, y } // Encode will encode the provided x and y coordinates into a Hilbert @@ -62,11 +61,11 @@ func rotate(n, rx, ry int32, x, y *int32) { func Encode(x, y int32) int64 { var rx, ry int32 var d int64 - for s := int32(n / 2); s > 0; s /= 2 { + for s := int32(n >> 1); s > 0; s >>= 1 { rx = boolToInt(x&s > 0) ry = boolToInt(y&s > 0) - d += int64(int64(s) * int64(s) * int64(((3 * rx) ^ ry))) - rotate(s, rx, ry, &x, &y) + d += int64(int64(s) * int64(s) * int64(rx<<1|(rx^ry))) + x, y = rotate(s, rx, ry, x, y) } return d @@ -79,13 +78,13 @@ func Decode(h int64) (int32, int32) { var x, y int32 t := h - for s := int64(1); s < int64(n); s *= 2 { - rx = 1 & (t / 2) + for s := int64(1); s < int64(n); s <<= 1 { + rx = 1 & (t >> 1) ry = 1 & (t ^ rx) - rotate(int32(s), int32(rx), int32(ry), &x, &y) + x, y = rotate(int32(s), int32(rx), int32(ry), x, y) x += int32(s * rx) y += int32(s * ry) - t /= 4 + t >>= 2 } return x, y