JavaScript从实数和整数中计算哈希码

Iva*_*tan 5 javascript html5 typescript

嗨,我需要函数来计算从数字(实数双精度)和整数的唯一整数.

尝试解释我正在开发javascript中的GIS应用程序,我正在使用复杂的矢量对象,如polygon(点对象数组,环中有两个坐标)和点数组.我需要快速算法来识别元素已被更改它必须非常快,因为我的矢量对象是千点的集合.在C#中,我使用按位运算XOR从坐标计算哈希码.

但是javascript将按位运算中的所有操作数转换为整数,但我需要在c#way(binnary)中按位置应用之前将双精度转换为整数.在反射器中,我看到c#计算哈希码这样的双倍,我需要这个函数在javascript中尽可能快.

public override unsafe int GetHashCode() //from System.Double
{
    double num = this;
    if (num == 0.0)
    {
        return 0;
    }
    long num2 = *((long*) &num);
    return (((int) num2) ^ ((int) (num2 >> 32)));
}
Run Code Online (Sandbox Code Playgroud)

例:

var rotation = function (n) {
    n = (n >> 1) | ((n & 0x001) << 31);
    return n;
}

var x: number = 1;
var y: number = 5;

var hash = x ^ rotation(y); // result is -2147483645

var x1: number = 1.1;
var y1: number = 5;

var hash1 = x1 ^ rotation(y1); // result is -2147483645
Run Code Online (Sandbox Code Playgroud)

示例结果不正确hash == hash1

示例2:使用字符串得到正确的结果但是从字符串计算哈希是复杂的,我的事情不够快.

    var rotation = function (n) {
        n = (n >> 1) | ((n & 0x001) << 31);
        return n;
    }

     var GetHashCodeString = function(str: string): number {
        var hash = 0, i, l, ch;
        if (str.length == 0) return hash;
        for (i = 0, l = str.length; i < l; i++) {
            ch = str.charCodeAt(i);
            hash = ((hash << 5) - hash) + ch;
            hash |= 0; // Convert to 32bit integer
        }
        return hash;
     }

    var x: number = 1;
    var y: number = 5;

    var hash = GetHashCodeString(x.toString()) ^ rotation(GetHashCodeString(y.toString()));
    //result is -2147483605
    var x1: number = 1.1;
    var y1: number = 5;

    var hash1 = GetHashCodeString(x1.toString()) ^ rotation(GetHashCodeString(y1.toString()));
   //result is -2147435090
Run Code Online (Sandbox Code Playgroud)

Example2结果是正确的hash!= hash1

有没有比将数字转换为字符串更快的方法而不是从每个字符计算哈希?因为我的物体非常大,以这种方式需要大量的时间和操作......

我尝试使用TypedArrays但是我没有成功.

非常感谢您的帮助

gle*_*ebm 1

这是在 JavaScript 中执行此操作的更快方法。

const kBuf = new ArrayBuffer(8);
const kBufAsF64 = new Float64Array(kBuf);
const kBufAsI32 = new Int32Array(kBuf);

function hashNumber(n) {
  // Remove this `if` if you want 0 and -0 to hash to different values.
  if (~~n === n) {
    return ~~n;
  }
  kBufAsF64[0] = n;
  return kBufAsI32[0] ^ kBufAsI32[1];
}
Run Code Online (Sandbox Code Playgroud)

它比方法快 250 倍DataView请参阅基准测试