为什么java方法Integer.toBinaryString(-128)输出七位数?

时间:2014-05-07 04:40:59

标签: java binary byte twos-complement

简单的场景: 你有一个字节数组

byte[] message = { 1, 2, 3 };

要以二进制打印出来,您可以使用以下代码:

for (byte b : message) {
    System.out.println(Integer.toBinaryString(0x100 + b).substring(1));
}

(从this stack overflow thread获得该代码)

获得此输出:

00000001
00000010
00000011



但如果你在最后标记-128 ......

byte[] message = { 1, 2, 3, -128 };

00000001
00000010
00000011
0000000

哇!七位二进制数?我觉得这与两个补充有关,但我试着读的越多,我就越困惑。我期待10000000出现在第四行而不是......

任何人都可以用相对简单的术语解释为什么Integer.toBinaryString的{​​{1}}是七位数?


Ye olde javadoc-128 但就像我说的那样......只是让我困惑。



这一切的背景是我尝试编写java中的一些SHA函数。不要问我为什么,我甚至都不知道......我只是好奇/挑战自我/挫败自己:)

根据the documentation在SHA-256函数中使用的消息的填充(使其为位长的512的倍数)是以下的串联:

  1. 原始讯息
  2. 单个The unsigned integer value is the argument plus 2^32 if the argument is negative; otherwise it is equal to the argument. This value is converted to a string of ASCII digits in binary (base 2) with no extra leading 0s.
  3. 1位到最后64位
  4. 原始邮件长度为64位值
  5. 由于我的消息很可能是ASCII 8位代码,我只需要为{2}标记0 ...然后我可以将10000000 BYTES的数量计算为加上,我不应该计划不是8的倍数的消息。问题在于0

2 个答案:

答案 0 :(得分:7)

(-128 + 0x100) =
(256 - 128) = 128 = 
0b10000000

Integer.toBinaryString(0b10000000) = "10000000"

"10000000".substring(1) = "0000000"

答案 1 :(得分:1)

您复制的堆栈溢出线程中存在错误。 0x100十进制为256,所以......

0x100 + 1 = 257 = 0b100000001 (9 digits)
0x100 + (-128) = 128 = 0b10000000 (8 digits)

换句话说,由于128小于Byte.MAX_VALUE,因此您无法获得海报所预期的填充效果。你可以选择一个更大的值来填充 - 尝试0x200并删除前两个字符??

FWIW,可以理解这些类型的错误b / c负字节值有点奇怪的java事情。哦,好吧。