Java中的无符号操作符

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,但由于时间紧迫,这有点复杂。希望有人能帮我解决这个问题。 谢谢

2个回答

4
代码几乎完全相同,只有%运算符不同。
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;
}

你能解释一下(或者提供一个解释的链接)这个解决方案是如何工作的吗?我想要自己理解它。 - BlackVegetable
1
第一种解决方案将 n 转换为从 0 到 0xFFFFFFFFL 的无符号值,执行 % 操作,然后再转换回 int。第二种方法只是确保该值始终介于 06 之间。 - Peter Lawrey
谢谢。这对我来说更清晰了(希望其他观众也是如此)。 - BlackVegetable

0
如果你将一个无符号整数值转换为长整型,你需要屏蔽掉符号扩展位:
int uintValue = 0x80706050;
long value = 0x00000000FFFFFFFFL & uintValue;

也许你在问题中指的是 0xFFFFFFFFL。而 0x00000000FFFFFFFF 是一个 int 类型,等于 -1 - Peter Lawrey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接