3

众所周知,Java 没有无符号类型。我必须将 C# 中的一个片段(使用 uint)转换为 Java。我的代码在这里:

private const int ROLLING_WINDOW = 7;
private const int HASH_PRIME = 0x01000193;
private unit h1, h2, h3, n;
private byte[] window;

//...

private uint roll_hash(byte c)
{
    h2 -= h1;
    h2 += (uint)ROLLING_WINDOW * c;

    h1 += c;
    h1 -= window[n % ROLLING_WINDOW];

    window[n % ROLLING_WINDOW] = c;
    n++;

    h3 = (h3 << 5);
    h3 ^= c;

    return h1 + h2 + h3;
}

private static uint sum_hash(byte c, uint h)
{
        h *= HASH_PRIME;
        h ^= c;
        return h;
}

在 Java 中,我使用long而不是,uint但结果有时会给出负值。解决方案是使用无符号运算符。一些搜索向我展示了关于 0xFFFFFFFFL 的信息,但在截止日期即将到来时它非常复杂。希望有人帮助我解决这个问题。谢谢

4

2 回答 2

3

代码几乎完全相同。只有 % 操作不同。

window[(int)((n & 0xFFFFFFFFL) % ROLLING_WINDOW)]

或者你可以写

window[n]

if(++n == ROLLING_WINDOW) n = 0;

更详细

private int roll_hash(byte c)
{
    h2 -= h1; // same
    h2 += ROLLING_WINDOW * c; // same, remove (uint)

    h1 += c; // same
    h1 -= window[n];

    window[n] = c;
    if(++n == ROLLING_WINDOW) n = 0; // limit n to 0 to 6 so % is not required.

    h3 = (h3 << 5); // same
    h3 ^= c; // same

    return h1 + h2 + h3; // same
}

private static int sum_hash(byte c, int h)
{
        h *= HASH_PRIME; // same
        h ^= c; // same
        return h;
}
于 2012-06-28T15:21:32.773 回答
0

如果您将一个未指定的整数值转换为长整数,则需要屏蔽符号扩展位:

int uintValue = 0x80706050;
long value = 0x00000000FFFFFFFFL & uintValue;
于 2012-06-28T15:23:18.503 回答