UInt8的否定

时间:2017-04-03 15:20:21

标签: java objective-c crc

我在Objective-C中有这个代码,我想用Java编写它。然而,有(-(crc & 1))声明给我带来了问题。在一些googeling之后,似乎无条件的否定通常没有明确定义。我虽然不太明白。也许知道CRC的人可以告诉我Java中的等价物是什么。

我需要一个等效的方法作为一个设备,这个Objective-C代码检查我的计算的crc与其自我计算。

+ (UInt32) crc32:(UInt32) crc ofByte: (UInt8) byte
{
    int8_t i;
    crc = crc ^ byte;
    for (i = 7; i >= 0; i--)
    {
        crc = (crc >> 1) ^ (0xedb88320ul & (-(crc & 1)));
    }
    return(crc);
}

在评论的帮助下解决了代码。好像我在错误的地方搜索了这个错误。

private void addByteToCRC(byte oneByte) {
    crc ^= oneByte & 0xFF;
    for (int i = 7; i >= 0; i--)
    {
        crc = (crc >>> 1) ^ (0xedb88320 & (-(crc & 1)));
    }
}

两个校验和都以crc值0xFFFFFFFF开始。

2 个答案:

答案 0 :(得分:1)

(Objective-)C和Java之间存在一些差异,但您可能已经发现了错误的问题。 Java没有无符号整数类型。但是它确实有按位运算符,它将整数视为只是位串,而后来的Java版本确实有无符号运算符,当应用于整数时,它们对基础位模式进行操作,就像它们表示无符号值一样。 / p>

表达式crc & 1将产生01的结果,具体取决于crc是偶数还是奇数。

表达式-(crc & 1)因此评估为0-10的位模式全为零,-1的位模式全部为1 - 后者在(目标 - )C中为真,无论整数的基础表示为1或2&# 39;补充,请参阅Is it safe to use -1 to set all bits to true?以获得解释。

表达式0xedb88320ul & (-(crc & 1))因此评估为00xedb88320

表达式crc >> 1逻辑无符号,在(Objective-)C中右移,因为src被定义为 unsigned 签名整数的右移是"实现定义"在(Objective-)C中)。

任何x ^ 0的表达式x评估为x

将所有内容放在一起,整个表达式(crc >> 1) ^ (0xedb88320ul & (-(crc & 1)))有条件地xors crc >> 10xedb88320基数不同,crc是奇数还是偶数。

现在您只需要在Java中重现相同的行为。

Java为intJLS: Primitive Types and Values)使用32位2的补码整数,并提供按位运算符,将它们视为位串。

十六进制常量仅为0xedb88320且具有int(32位)类型。

表达式-(crc & 1)因此评估为(目标 - )C。

然而,表达式crc >> 1评估与(Objective-)C中的相同。在Java中,>>算术右移,它在移位期间复制符号位。这个选择源于使用签名类型的Java。幸运的是,Java还提供>>>运算符来执行逻辑无符号,右移。

所以我猜您可能在转换中发现了错误的问题,并且您需要使用>>>运算符。

HTH

答案 1 :(得分:1)

-(crc & 1)工作正常,不是你的问题。它的作用是将crc的低位复制到所有位,因为在二进制补码表示中,-1都是1。

您需要为Java修复两件事,它没有无符号整数。首先,正确的转变需要是一个合乎逻辑的右移>>>。这避免了在向下移位时复制符号位,而是在零位移位。其次,您需要防止签名扩展到int的字符,因此byte(需要在Java中使用不同的名称)需要使用0xff。所以:

crc ^= octet & 0xff;

crc = (crc >>> 1) ^ (0xedb88320ul & (-(crc & 1)));