简体   繁体   English

"Java负整数到十六进制并返回失败"

[英]Java negative int to hex and back fails

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));
    }
}

It's documented that Integer.toHexString returns a string representation of the integer as an unsigned value - while Integer.parseInt takes a signed int. 据记载, Integer.toHexString将整数的字符串表示形式返回为无符号值 - 而Integer.parseInt采用带符号的int。 If you use Integer.toString(value, 16) instead you'll get what you want. 如果您使用Integer.toString(value, 16)那么您将得到您想要的。

This is something that's always annoyed me. 这总是令我恼火的事情。 If you initialize an int with a hex literal, you can use the full range of positive values up to 0xFFFFFF ; 如果使用十六进制文字初始化int,则可以使用最大为0xFFFFFF的全范围正值; anything larger than 0x7FFFFF will really be a negative value. 任何大于0x7FFFFF东西都是负值。 This is very handy for bit masking and other operations where you only care about the locations of the bits, not their meanings. 这对于位掩码和其他操作非常方便,您只关心位的位置 ,而不是它们的含义。

But if you use Integer.parseInt() to convert a string to an integer, anything larger than "0x7FFFFFFF" is treated as an error. 但是,如果使用Integer.parseInt()将字符串转换为整数,则将大于"0x7FFFFFFF"任何内容视为错误。 There's probably a good reason why they did it that way, but it's still frustrating. 可能有一个很好的理由为什么他们这样做,但它仍然令人沮丧。

The simplest workaround is to use Long.parseLong() instead, then cast the result to int. 最简单的解决方法是使用Long.parseLong()代替,然后将结果转换为int。

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

Of course, you should only do that if you're sure the number is going to be in the range Integer.MIN_VALUE..Integer.MAX_VALUE . 当然,只有在确定数字将在Integer.MIN_VALUE..Integer.MAX_VALUE范围内时才应该这样做。

According the the documentation, toHexString returns "a string representation of the integer argument as an unsigned integer in base 16. " 根据文档, toHexString返回“整数参数的字符串表示形式,作为基数为16的无符号整数。”

So the correct reverse operation is probably Integer.parseUnsignedInt that was introduced as part of Java 8: 因此正确的反向操作可能是作为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));
    }

Try this: 试试这个:

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));
    }

} }

to get this: 得到这个:

-2147483648 80000000
-2147483648

You need to include a negative sign. 你需要包含一个负号。

I don't have access to test this right now but I'd bet if you tried this value instead: 我现在没有权限对此进行测试,但如果您尝试使用此值,我会打赌:

Integer min = Integer.MIN_VALUE + 1;

It wouldn't bomb, but would give you a positive number (not negative) when you ran ParseInt(min,16) . 它不会炸弹,但是当你运行ParseInt(min,16)时会给你一个正数(不是负数ParseInt(min,16)

A string of bits doesn't really have enough info to determine sign in this context so you need to provide it. 一串位实际上没有足够的信息来确定此上下文中的符号,因此您需要提供它。 (consider the case where you use min = "F" . Is that +/-F? If you converted it to bits and saw 1111, and you knew it was a byte, you might conclude that it's negative, but that's a lot of ifs. (考虑使用min = "F" 。那是+/- F吗?如果你将它转换为位并看到1111, 并且你知道它是一个字节,你可能会认为它是负数,但这是很多IFS。

This seem to work for me : 这似乎对我有用:

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));
}
}

The integer is parsed as a "signed long" that handle such big positive number and then the sign is found back by casting it to "int". 整数被解析为处理这么大的正数的“有符号长整数”,然后通过将其转换为“int”来找回符号。

Integer.parseInt() takes in a signed integer as it's input. Integer.parseInt()将有符号整数作为输入。 This means the input has to be between "7FFFFFFF" and "-80000000".这意味着输入必须在“7FFFFFFF”和“-80000000”之间。 Note the negative sign before "80000000".注意“80000000”之前的负号。 What you want is Integer.parseInt("-80000000", 16) .你想要的是Integer.parseInt("-80000000", 16) If you use 80000000 without the minus sign Java will interpret that as a positive number and throw an exception because the max positive integer for an int is 0x7FFFFFFF.如果使用不带减号的 80000000,Java 会将其解释为正数并抛出异常,因为 int 的最大正整数为 0x7FFFFFFF。

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

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