简体   繁体   English

在 Java 中转换十六进制,负值的错误值

[英]Converting Hex in Java, wrong value with negative values

I have seen several questions on the topic mentioned in the subject (eg this one ), but it seems to me that none of them provided this example.我已经看到关于主题中提到的主题的几个问题(例如这个),但在我看来,他们都没有提供这个例子。 I'm using Java7 and I want to convert a String representing an hexadecimal or a decimal into an Integer or Long value (depends on what it represents) and I do the following:我正在使用 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;
    }
}

When I use a String representing a decimal number everything is ok, the problem are arising with negative hexadecimals当我使用代表十进制数的字符串时,一切正常,问题出在负十六进制

Now, If I do:现在,如果我这样做:

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

fails, because it returns a Long .失败,因为它返回一个Long Same for other negative integer values.其他负整数值相同。

Moreover, when I use Long.MIN_VALUE like in the following:此外,当我使用Long.MIN_VALUE时,如下所示:

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

fails, because of NumberFormatException with message:失败,因为NumberFormatException与消息:

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

I also tried with other random Long values (so within the Long.MIN_VALUE and Long.MAX_VALUE, and it fails as well when I have negative numbers. Eg我还尝试了其他随机Long值(因此在 Long.MIN_VALUE 和 Long.MAX_VALUE 内,当我有负数时它也会失败。例如

the String with the hexadecimal 0xc0f1a47ba0c04d89 for the Long number -4,543,669,698,155,229,815 returns:带有十六进制0xc0f1a47ba0c04d89String用于Long-4,543,669,698,155,229,815返回:

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

How can I fix the script to obtain the desired behavior?如何修复脚本以获得所需的行为?

Long.decode and Integer.decode do not accept complemented values such as returned by Integer.toHexString : the sign should be represented as a leading - as described by the DecodableString grammars found in the javadoc . Long.decodeInteger.decode不接受补充值,例如Integer.toHexString返回的值:符号应表示为前导-javadoc 中的 DecodableString 语法所述。

The sequence of characters following an optional sign and/or radix specifier ("0x", "0X", "#", or leading zero) is parsed as by the Long.parseLong method with the indicated radix (10, 16, or 8).跟随可选符号和/或基数说明符(“0x”、“0X”、“#”或前导零)的字符序列被 Long.parseLong 方法解析为具有指示的基数(10、16 或 8 )。 This sequence of characters must represent a positive value or a NumberFormatException will be thrown.此字符序列必须表示正值,否则将抛出 NumberFormatException。 The result is negated if first character of the specified String is the minus sign如果指定 String 的第一个字符是减号,则结果是否定的

If you can change the format of your input String , then produce it with Integer.toString(value, 16) rather than Integer.toHexString(value) .如果您可以更改输入String的格式,则使用Integer.toString(value, 16)而不是Integer.toHexString(value)生成它。

If you can switch to Java 8, use parseUnsignedInt/Long .如果您可以切换到 Java 8,请使用parseUnsignedInt/Long

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM