【问题标题】:Java negative int to hex and back failsJava负整数到十六进制并返回失败
【发布时间】:2010-10-25 02:51:21
【问题描述】:
public class Main3 {
    public static void main(String[] args) {
        Integer min = Integer.MIN_VALUE;
        String minHex = Integer.toHexString(Integer.MIN_VALUE);

        System.out.println(min + " " + minHex);
        System.out.println(Integer.parseInt(minHex, 16));
    }
}

-2147483648 80000000
Exception in thread "main" java.lang.NumberFormatException: For input string: "80000000"
    at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48)
    at java.lang.Integer.parseInt(Integer.java:459)
    at Main3.main(Main3.java:7)

怎么了?

【问题讨论】:

    标签: java parsing decimal hex signed


    【解决方案1】:

    据记载,Integer.toHexString 将整数的字符串表示形式作为无符号值返回 - 而 Integer.parseInt 采用有符号整数。如果你改用Integer.toString(value, 16),你会得到你想要的。

    【讨论】:

    • 如果有一种方法可以将十六进制转换为整数/长整数,只需放置位而不关心符号就可以了。这样就可以以最小的开销来回转换。
    【解决方案2】:

    根据文档,toHexString 返回 “整数参数的字符串表示形式,以 16 为底的 无符号 整数。”

    所以正确的反向操作可能是作为 Java 8 的一部分引入的Integer.parseUnsignedInt

    public class Main3 {
        public static void main(String[] args) {
            Integer min = Integer.MIN_VALUE;
            String minHex = Integer.toHexString(Integer.MIN_VALUE);
    
            System.out.println(min + " " + minHex);
            System.out.println(Integer.parseUnsignedInt(minHex, 16));
        }
    

    【讨论】:

      【解决方案3】:

      这似乎对我有用:

      public class Main3 {
      public static void main(String[] args) {
          Integer min = Integer.MIN_VALUE;
          String minHex = Integer.toHexString(Integer.MIN_VALUE);
      
          System.out.println(min + " " + minHex);
          System.out.println((int)Long.parseLong(minHex, 16));
      }
      }
      

      整数被解析为处理如此大的正数的“有符号长整数”,然后通过将其转换为“整数”来找到符号。

      【讨论】:

        【解决方案4】:

        这一直是让我烦恼的事情。如果使用十六进制字面量初始化 int,则可以使用最大范围为 0xFFFFFF 的正值;任何大于0x7FFFFF 的东西都将是一个负值。这对于位掩码和其他您只关心位的位置而不是它们的含义的操作非常方便。

        但是如果您使用 Integer.parseInt() 将字符串转换为整数,则任何大于"0x7FFFFFFF" 的内容都会被视为错误。他们这样做可能有一个很好的理由,但这仍然令人沮丧。

        最简单的解决方法是改用 Long.parseLong(),然后将结果转换为 int。

        int n = (int)Long.parseLong(s, 16);
        

        当然,只有当您确定该数字将在Integer.MIN_VALUE..Integer.MAX_VALUE 范围内时,您才应该这样做。

        【讨论】:

          【解决方案5】:

          试试这个:

          public class Main3 {
              public static void main(String[] args) {
                  Integer min = Integer.MIN_VALUE;
                  String minHex = Integer.toHexString(Integer.MIN_VALUE);
          
                  System.out.println(min + " " + minHex);
                  System.out.println(Integer.parseInt( "-" + minHex, 16));
              }
          

          }

          得到这个:

          -2147483648 80000000
          -2147483648
          

          【讨论】:

            【解决方案6】:

            你需要include a negative签名。

            我现在无权对此进行测试,但我敢打赌,如果您尝试使用此值:

            Integer min = Integer.MIN_VALUE + 1;
            

            它不会爆炸,但在您运行 ParseInt(min,16) 时会给您一个正数(不是负数)。

            string 位并没有足够的信息来确定此上下文中的符号,因此您需要提供它。 (考虑您使用min = "F" 的情况。这是 +/-F 吗?如果您将其转换为位并看到 1111,并且您知道它是一个字节,您可能会得出结论它是负数,但这是很多如果。

            【讨论】:

              猜你喜欢
              • 2016-02-24
              • 2015-08-17
              • 2018-12-06
              • 2020-02-09
              • 2021-12-17
              • 2014-11-30
              • 2022-12-13
              • 2019-06-16
              相关资源
              最近更新 更多