在Java中转换Hex,使用负值转换错误的值

时间:2016-10-07 09:52:46

标签: java hex decimal

我已经看到了关于该主题中提到的主题的几个问题(例如this one),但在我看来,他们都没有提供这个例子。我使用的是Java7,我希望将表示十六进制或十进制的String转换为IntegerLong值(取决于它代表的含义)并执行以下操作:

public Number getIntegerOrLong(String num) {
    try {
        return Integer.decode(num);
    } catch (NumberFormatException nf1) {
        final long decodedLong = Long.decode(num);
        if ((int) decodedLong == decodedLong) {//used in Java8 java.util.Math.toIntExact()
            return (int) decodedLong;
        }
        return decodedLong;
    }
}

当我使用表示十进制数字的字符串时,一切正常,问题是由负十六进制产生的

现在,如果我这样做:

String hex = "0x"+Integer.toHexString(Integer.MIN_VALUE);
Object number = getIntegerOrLong(hex);
assertTrue(number instanceof Integer):

失败,因为它返回Long。与其他负整数值相同。

此外,当我使用Long.MIN_VALUE时,如下所示:

String hex = "0x"+Integer.toHexString(Long.MIN_VALUE);
Object number = getIntegerOrLong(hex);
assertTrue(number instanceof Long):

失败,因为NumberFormatException有消息:

java.lang.NumberFormatException: For input string: "8000000000000000"

我也试过了其他随机Long值(所以在Long.MIN_VALUE和Long.MAX_VALUE中,当我有负数时它也会失败。例如。

String 0xc0f1a47ba0c04d89号码Long的{​​{1}}返回:

-4,543,669,698,155,229,815

如何修复脚本以获得所需的行为?

1 个答案:

答案 0 :(得分:2)

Long.decodeInteger.decode不接受由Integer.toHexString返回的补充值:该符号应表示为前导-,如下所示的DecodableString语法所述javadoc

  

可选符号和/或基数说明符(“0x”,“0X”,“#”或前导零)后面的字符序列由Long.parseLong方法解析,并带有指示的基数(10,16) ,或8)。此字符序列必须表示正值或将抛出NumberFormatException。如果指定String的第一个字符是减号

,则结果为否定

如果您可以更改输入String的格式,请使用Integer.toString(value, 16)而不是Integer.toHexString(value)生成输入格式。

如果您可以切换到Java 8,请使用parseUnsignedInt/Long