【问题标题】:Two's complement giving different answer in java二进制补码在java中给出不同的答案
【发布时间】:2021-09-23 20:39:51
【问题描述】:

抱歉,如果我的问题是基本问题或与其他问题重复。无论如何,我正在尝试执行二进制补码来更改数字的符号并检查 java 中的结果,但结果与我手动计算的结果不同。

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

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

你能帮帮我吗?

【问题讨论】:

  • should be 11111000 - 没有。打印出来,你自己看看。
  • 那是 -8 作为二进制的 byte,当然。对于int,在开头再添加 24 个 1。
  • 看看 BigInteger ;-)

标签: java binary bit-manipulation bitwise-operators twos-complement


【解决方案1】:

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

将字符串参数解析为第二个参数指定的基数中的有符号整数。字符串中的字符必须都是指定基数的数字(由 Character.digit(char, int) 是否返回非负值决定),除了第一个字符可能是 ASCII 减号 '-' ('\u002D ') 表示负值或 ASCII 加号 '+' ('\u002B') 表示正值。返回结果整数值。

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

【讨论】:

    【解决方案2】:

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

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

    正如方法所说,“解析这个数字”。 2 的补码并不是普通人所理解的有效数学。

    如果我拿着麦克风出去,在一张纸上写下 11111000,然后随便问街上的人:这是以 2 为底的,它是什么数字 - 你希望他们说 -8,你显然已经走深了。

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

    好的,那我该怎么做呢?

    实际上并没有直接的方法,2 的补码是你可以观察到的实现细节,但它永远不会让你默默地写(无论是字符串形式还是文字形式)a正数,无论是位还是十进制或十六进制,但仍将字面解析为负数。

    因此,我们尝试观察它。投射效果很好:

    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 用于写base 2,只写base 10 的数字,base 8 前面加0,base 16 前面加上0x0x10 == 16 == 0b10000 == 020。试试看!

    • 将 int 转换为字节将占用您的 32 位,去掉“最左边”的 24 位,然后将剩余的 8 位直接推入一个字节,如果这意味着该数字现在为负数,那就这样吧。这是 java 中为数不多的允许 2s 补码影响发生的事情(相对于扔东西)的概念的操作之一。

    【讨论】:

      猜你喜欢
      • 2023-03-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-20
      • 2015-06-25
      • 1970-01-01
      • 2016-04-23
      相关资源
      最近更新 更多