添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
int FirstAttempt=Integer.parseInt(Hex,16); // Error "Invalid Int"
int SecondAttempt=Integer.decode("0x"+Hex);  // Error "Invalid Int"

所以,一开始,它把数值-32768转换为十六进制字符串fff8000,但随后它不能把十六进制字符串再转换为整数。

.Net中,它像我所期望的那样工作,而returns -32768

我知道我可以自己写一个小方法来转换,但我只是想知道我是否错过了什么,或者这真的是一个错误?

2 个评论
提示:按照惯例,变量名称以小写字母开头。int firstAttempt = 5;
java
string
hex
Rich S
Rich S
发布于 2012-08-17
10 个回答
brimborium
brimborium
发布于 2012-08-17
已采纳
0 人赞同
int val = -32768;
String hex = Integer.toHexString(val);
int parsedResult = (int) Long.parseLong(hex, 16);
System.out.println(parsedResult);

这就是你可以做的。

之所以不按你的方式工作,是因为。Integer.parseInt需要一个有符号的int,而toHexString产生一个无符号的结果。因此,如果你插入高于0x7FFFFFF的东西,就会自动抛出一个错误。如果你把它解析为long,它仍将是有符号的。但是当你把它投回int时,它将溢出到正确的值。

roni bar yanai
roni bar yanai
发布于 2012-08-17
0 人赞同

它溢出了,因为这个数字是负数。

试试这个,会有效果的。

int n = (int) Long.parseLong("ffff8000", 16);
    
谢谢罗尼,这似乎是最好的解决办法。尽管Int.parseInt没有像我所期望的那样工作,这仍然很奇怪。
ffff8000不适合于一个int(比max int大),这是一个正数(它是一个字符串,所以只有当它有减号时才是负数)。
这是因为parseInt需要一个有符号的int,而toHexString产生一个无符号的结果(见我的回答)...
谢谢你,你拯救了我。)
@roni, 如果十六进制是字符串值,如String Hex=Integer.toHexString("xyz");,如何从十六进制中取回字符串作为 "xyz"。
user1122857
user1122857
发布于 2012-08-17
0 人赞同
  • int to Hex :

    Integer.toHexString(intValue);
    
  • Hex to int :

    Integer.valueOf(hexString, 16).intValue();
    

    你也可能想使用long而不是int(如果数值不符合int的界限)。

  • Hex to long:

    Long.valueOf(hexString, 16).longValue()
    
  • long to Hex

    Long.toHexString(longValue)
        
  • Yuval Sapir
    Yuval Sapir
    发布于 2012-08-17
    0 人赞同

    值得一提的是,Java 8有Integer.parseUnsignedIntLong.parseUnsignedLong的方法,专门做你想要的事情。

    Integer.parseUnsignedInt("ffff8000",16) == -32768

    这个名字有点令人困惑,因为它从一个十六进制字符串中解析出一个有符号的整数,但它做了这个工作。

    maneesh
    maneesh
    发布于 2012-08-17
    0 人赞同

    试试使用BigInteger类,它可以工作。

    int Val=-32768;
    String Hex=Integer.toHexString(Val);
    //int FirstAttempt=Integer.parseInt(Hex,16); // Error "Invalid Int"
    //int SecondAttempt=Integer.decode("0x"+Hex);  // Error "Invalid Int"
    BigInteger i = new BigInteger(Hex,16);
    System.out.println(i.intValue());
        
    Pwnstar
    Pwnstar
    发布于 2012-08-17
    0 人赞同

    由于Integer.toHexString(byte/integer)在你试图转换像UTF-16解码的字符那样的有符号的字节时是不起作用的,你必须使用。

    Integer.toString(byte/integer, 16);
    
    String.format("%02X", byte/integer);
    

    反之,你可以使用

    Integer.parseInt(hexString, 16);
        
    Benj
    Benj
    发布于 2012-08-17
    0 人赞同

    Java的parseInt方法实际上是一堆吃 "假 "十六进制的代码:如果你想翻译-32768,你应该把绝对值转换成十六进制,然后在字符串前面加上'-'。

    这里有一个Integer.java文件的样本。

    public static int parseInt(String s, int radix)
    

    The description is quite explicit :

    * Parses the string argument as a signed integer in the radix 
    * specified by the second argument. The characters in the string 
    * parseInt("0", 10) returns 0
    * parseInt("473", 10) returns 473
    * parseInt("-0", 10) returns 0
    * parseInt("-FF", 16) returns -255
        
    Chef Pharaoh
    Chef Pharaoh
    发布于 2012-08-17
    0 人赞同

    使用Integer.toHexString(...)是一个不错的答案。但个人更喜欢用String.format(...)

    试试这个样本作为一个测试。

    byte[] values = new byte[64];
    Arrays.fill(values, (byte)8);  //Fills array with 8 just for test
    String valuesStr = "";
    for(int i = 0; i < values.length; i++)
        valuesStr += String.format("0x%02x", values[i] & 0xff) + " ";
    valuesStr.trim();
        
    user7258708
    user7258708
    发布于 2012-08-17
    0 人赞同

    Below code would work:

    int a=-32768;
    String a1=Integer.toHexString(a);
    int parsedResult=(int)Long.parseLong(a1,16);
    System.out.println("Parsed Value is " +parsedResult);
        
    pap
    pap
    发布于 2012-08-17
    0 人赞同

    嘿嘿,很好奇。我想这是一个 "故意的错误",可以这么说。

    其根本原因在于Integer类的编写方式。基本上,parseInt对正数进行了 "优化"。当它解析字符串时,它以累积的方式建立结果,但要进行否定。然后它将最终结果的符号翻转。

    66 = 0x42

    被解析成这样。

    4*(-1) = -4
    -4 * 16 = -64 (hex 4 parsed)
    -64 - 2 = -66 (hex 2 parsed)
    return -66 * (-1) = 66
    

    现在,让我们看一下你的例子 FFFF8000

    16*(-1) = -16 (first F parsed)
    -16*16 = -256 
    -256 - 16 = -272 (second F parsed)
    -272 * 16 = -4352 
    -4352 - 16 = -4368 (third F parsed)
    -4352 * 16 = -69888
    -69888 - 16 = -69904 (forth F parsed)
    -69904 * 16 = -1118464 
    -1118464 - 8 = -1118472 (8 parsed)
    -1118464 * 16 = -17895552 
    -17895552 - 0 = -17895552 (first 0 parsed)
    Here it blows up since -17895552 < -Integer.MAX_VALUE / 16 (-134217728). 
    Attempting to execute the next logical step in the chain (-17895552 * 16)
    would cause an integer overflow error.
    

    Edit (addition): in order for the parseInt() to work "consistently" for -Integer.MAX_VALUE <= n <= Integer.MAX_VALUE, they would have had to implement logic to "rotate" when reaching -Integer.MAX_VALUE in the cumulative result, starting over at the max-end of the integer range and continuing downwards from there. Why they did not do this, one would have to ask Josh Bloch or whoever implemented it in the first place. It might just be an optimization.

    However,

    Hex=Integer.toHexString(Integer.MAX_VALUE);
    System.out.println(Hex);
    System.out.println(Integer.parseInt(Hex.toUpperCase(), 16));