我正在尝试实现空间哈希,并使用Optimized Spatial Hashing for Collision Detection of Deformable Objects中的哈希函数,hash(x, y, z) = (x p1 xor y p2 xor z p3) mod n
其中n是哈希表中的桶数。
哈希函数的代码是:
int SpatialHash::hash(int x, int y, int z)
{
return (((x * P1) ^ (y * P2) ^ (z * P3)) % TABLE_SIZE);
}
with definitions:
#define P1 73856093
#define P2 19349663
#define P3 83492791
#define TABLE_SIZE 2000
我只是尝试遍历一个元素列表,当我试图将顶点1,-1,0放入表格时,它给了我一个-196的索引。我用哈希函数搞砸了吗?
答案 0 :(得分:2)
负数的模数为负数。例如:
-7 % 3 = -1
想要这样的东西代替:
int positiveModulo(int number, int modulo)
{
int result = number % mudulo;
if (result < 0)
result += modulo;
return result;
}
或者避免分支:
int positiveModulo(int number, int modulo)
{
int result = number % mudulo;
result += modulo;
result %= modulo;
return result;
}
这会给你:
positiveModulo(-7, 3) = 2
答案 1 :(得分:1)
这实际上是一个有趣的问题,因为模运算结果的符号是编程语言设计者和数学家喜欢争论的东西。
实际上,在ISO C ++中,带负操作数的模运算符号是实现定义的。
聪明的语言有mod
和rem
来捕获这两种情况。
查看wikipedia page及其编程语言表。
有趣的是它如何在50:50左右分裂。
现在解决您的问题:只需添加一个正模运算。
最简单的解决方案是使用abs(...) % N
作为(-a) mod N + a mod N = 0
。
答案 2 :(得分:0)
#include <iostream>
#include <vector>
using namespace std;
#define P1 73856093
#define P2 19349663
#define P3 83492791
#define TABLE_SIZE 2000
int positive_mod(int i, int n)
{
/* constexpr */ int shift = 64*sizeof i - 1;
int m = i%n;
return m+ (m>>shift & n);
}
int hasha(int x, int y, int z)
{
return positive_mod(((x * P1) ^ (y * P2) ^ (z * P3)) ,TABLE_SIZE);
}
int main(int argc, char **argv)
{
int ret = hasha(1,-1,0);
cout << ret << endl;
}