UInt8 的负数
Negative of UInt8
我在Objective-C中有这段代码,我想在Java中编写它。但是,(-(crc & 1))
语句给我带来了问题。经过一番谷歌搜索后,似乎 unsigned 的负数通常没有明确定义。虽然我不太明白。也许知道 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)));
}
}
两个校验和都以 0xFFFFFFFF 的 crc 值开始。
(Objective-)C 和 Java 之间存在一些差异,但据推测您可能发现了错误的问题。 Java 没有无符号整数类型。然而,它确实有按位运算符将整数视为只是位串,并且 Java 的更高版本确实有无符号 运算符 ,当应用于整数时,它们对底层位模式进行操作作为尽管它们代表无符号值。
表达式 crc & 1
将产生 0
或 1
的结果,具体取决于 crc
是偶数还是奇数。
因此,表达式 -(crc & 1)
的计算结果为 0
或 -1
。 0
的位模式全为 0,而 -1
的位模式全为 1 - 后者在 (Objective-)C 中为真,而不管整数的底层表示为 1 或 2 的补码, 请参阅 Is it safe to use -1 to set all bits to true? 了解解释。
因此,表达式 0xedb88320ul & (-(crc & 1))
的计算结果为 0
或 0xedb88320
。
表达式crc >> 1
是逻辑,或无符号,向右移(Objective-) C as src
被定义为 unsigned (signed 整数的右移是 "implementation defined" in (Objective -)C)。
任何 x
的表达式 x ^ 0
的计算结果为 x
。
把它们放在一起,你的整个表达式 (crc >> 1) ^ (0xedb88320ul & (-(crc & 1)))
有条件地将 crc >> 1
与 0xedb88320
进行异或运算,不管 crc
是奇数还是偶数。
现在您只需要在 Java 中重现相同的行为。
Java 对 int
(JLS: Primitive Types and Values) 使用 32 位 2 的补码整数,并提供将它们视为位串的位运算符。
十六进制常量刚好 0xedb88320
并且具有 int
(32 位)类型。
因此,表达式 -(crc & 1)
的计算结果与 (Objective-)C 中的一样。
然而,表达式 crc >> 1
将 而不是 与 (Objective-)C 中的计算结果相同。在 Java 中,>>
是一个 算术 右移,它在移位期间复制符号位。此选择源于 Java 使用签名类型。幸运的是 Java 还提供了 >>>
运算符来执行 logical,或 unsigned,右移 [=41] =]
所以我猜你可能在转换中发现了错误的问题,你需要使用 >>>
运算符。
HTH
-(crc & 1)
工作正常,不是你的问题。它所做的是将 crc
的低位复制到所有位,因为在二进制补码表示中,–1 是全 1。
对于没有无符号整数的 Java,您需要解决两件事。首先是右移需要是逻辑右移,>>>
。这避免了在向下移动时复制符号位,而是移入零位。其次,您需要防止字符被符号扩展为 int
,因此 byte
(在 Java 中需要不同的名称)需要与 [=17= 相加].所以:
crc ^= octet & 0xff;
和
crc = (crc >>> 1) ^ (0xedb88320ul & (-(crc & 1)));
我在Objective-C中有这段代码,我想在Java中编写它。但是,(-(crc & 1))
语句给我带来了问题。经过一番谷歌搜索后,似乎 unsigned 的负数通常没有明确定义。虽然我不太明白。也许知道 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)));
}
}
两个校验和都以 0xFFFFFFFF 的 crc 值开始。
(Objective-)C 和 Java 之间存在一些差异,但据推测您可能发现了错误的问题。 Java 没有无符号整数类型。然而,它确实有按位运算符将整数视为只是位串,并且 Java 的更高版本确实有无符号 运算符 ,当应用于整数时,它们对底层位模式进行操作作为尽管它们代表无符号值。
表达式 crc & 1
将产生 0
或 1
的结果,具体取决于 crc
是偶数还是奇数。
因此,表达式 -(crc & 1)
的计算结果为 0
或 -1
。 0
的位模式全为 0,而 -1
的位模式全为 1 - 后者在 (Objective-)C 中为真,而不管整数的底层表示为 1 或 2 的补码, 请参阅 Is it safe to use -1 to set all bits to true? 了解解释。
因此,表达式 0xedb88320ul & (-(crc & 1))
的计算结果为 0
或 0xedb88320
。
表达式crc >> 1
是逻辑,或无符号,向右移(Objective-) C as src
被定义为 unsigned (signed 整数的右移是 "implementation defined" in (Objective -)C)。
任何 x
的表达式 x ^ 0
的计算结果为 x
。
把它们放在一起,你的整个表达式 (crc >> 1) ^ (0xedb88320ul & (-(crc & 1)))
有条件地将 crc >> 1
与 0xedb88320
进行异或运算,不管 crc
是奇数还是偶数。
现在您只需要在 Java 中重现相同的行为。
Java 对 int
(JLS: Primitive Types and Values) 使用 32 位 2 的补码整数,并提供将它们视为位串的位运算符。
十六进制常量刚好 0xedb88320
并且具有 int
(32 位)类型。
因此,表达式 -(crc & 1)
的计算结果与 (Objective-)C 中的一样。
然而,表达式 crc >> 1
将 而不是 与 (Objective-)C 中的计算结果相同。在 Java 中,>>
是一个 算术 右移,它在移位期间复制符号位。此选择源于 Java 使用签名类型。幸运的是 Java 还提供了 >>>
运算符来执行 logical,或 unsigned,右移 [=41] =]
所以我猜你可能在转换中发现了错误的问题,你需要使用 >>>
运算符。
HTH
-(crc & 1)
工作正常,不是你的问题。它所做的是将 crc
的低位复制到所有位,因为在二进制补码表示中,–1 是全 1。
对于没有无符号整数的 Java,您需要解决两件事。首先是右移需要是逻辑右移,>>>
。这避免了在向下移动时复制符号位,而是移入零位。其次,您需要防止字符被符号扩展为 int
,因此 byte
(在 Java 中需要不同的名称)需要与 [=17= 相加].所以:
crc ^= octet & 0xff;
和
crc = (crc >>> 1) ^ (0xedb88320ul & (-(crc & 1)));