两个补码在java中给出不同的答案



如果我的问题是基本问题或与另一个问题重复,很抱歉。无论如何,我正在尝试执行2的补码来更改数字的符号,并在java中检查结果,但结果与我手工计算的结果不同。

例如:
二进制中的8是00001000
执行2的补码后二进制中的-8应该是11111000

但是当我使用Integer.parseInt("11111000",2)而不是-8时,我得到248。
我是误解了2的补码概念,还是Java中有我不知道的东西。

你能帮我一下吗?

我是误解了2的补码概念,还是Java中有我不知道的东西。

是的,您错过的是Integer.parseInt("ones and zeroes", 2)而不是java ese:这里有一些位,请给我int值,它就是这个确切的位序列。

正如该方法所说;解析这个数字;。2的补码不是街上普通人所理解的有效数学。

如果我拿着麦克风,走出去,在一张纸上写下11111000,随机问街上的人:这是基数2,是多少——你希望他们说-8,你显然已经偏离了底线。

需要明确的是,Integer.parseInt永远不会给你一个负数,除非你传递给它的字符串以减号开头。它会给你一一个正数,或者如果字符串中的数字不适合int数字的正空间,它会崩溃。

好的,那么我该怎么做呢

实际上没有直接的方法,2的补码是可以观察到的一个实现细节,但它永远不会让你安静地写(无论是以字符串形式还是文字形式(一个正数,无论是以位、十进制还是十六进制,尽管如此,它还是可以从文字上解析为负数。

所以,我们试着去观察它。铸造将发挥巨大作用:

int x = 248;
int y = 0b11111000;
// x and y are the exact same value. `javap -c` to observe:
// they are _Exactly_ identical and it is hence impossible to tell the difference.
System.out.println(x == y); // prints true
byte b = (byte) x;
System.out.println(b); // prints -8

这里使用的概念:

  • 0b111000这只是一种不同的写入整数文字的方式。0x110b1之间没有差异——都是值1。所有的数字最后都是位。它们不储存它们是如何制作的。0b用于在基数2中写入,只需为基数10写入数字,为基数8在0之前,为基数16在0x之前:0x10==16==0b10000==020。试试看!

  • 将int转换为一个字节将占用32位,去掉"最左边"的24位,然后将剩余的8位直接推入一个字节,如果这意味着数字现在是负数,那就顺其自然吧。这是java中极少数允许2s补码影响发生的事情(与抛出一些东西相比(的操作之一。

如果您查看javadoc,您将看到:

将字符串参数解析为第二个参数指定基数的带符号整数。字符串中的字符都必须是指定基数的数字(由Character.digh(char,int(是否返回非负值决定(,但第一个字符可以是ASCII减号"-"("\u002D"(表示负值,也可以是ASCII加号"+"("\u002B"(表示正值。返回得到的整数值。

Java的Integer.parseInt不接受2-完成字符串。事实上,如果您提供一个32个字符的字符串,您将得到一个异常(最左边的位在内部为符号保留(。

最新更新