java将int转换为hex并再次转换

8e2ybdfx  于 2021-07-09  发布在  Java
关注(0)|答案(10)|浏览(1208)

我有以下代码。。。

  1. int Val=-32768;
  2. String Hex=Integer.toHexString(Val);

这等于 ffff8000 ```
int FirstAttempt=Integer.parseInt(Hex,16); // Error "Invalid Int"
int SecondAttempt=Integer.decode("0x"+Hex); // Error "Invalid Int"

  1. 因此,最初,它将值-32768转换为十六进制字符串ffff8000,但随后无法将十六进制字符串转换回整数。
  2. `.Net` 就像我预期的那样,而且 `returns -32768` .
  3. 我知道我可以自己编写一个小方法来转换它,但我只是想知道我是否遗漏了什么,或者这是否真的是一个bug
vbkedwbf

vbkedwbf1#

当您试图转换有符号字节(如必须使用的utf-16解码字符)时,as integer.tohexstring(byte/integer)不起作用:

  1. Integer.toString(byte/integer, 16);

  1. String.format("%02X", byte/integer);

你可以用倒过来

  1. Integer.parseInt(hexString, 16);
crcmnpdw

crcmnpdw2#

int 到十六进制:

  1. Integer.toHexString(intValue);

十六进制到 int :

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

您也可以使用 long 而不是 int (如果值不符合 int 界限):
十六进制到 long :

  1. Long.valueOf(hexString, 16).longValue()
  2. ``` `long` 到十六进制

Long.toHexString(longValue)

展开查看全部
bttbmeg0

bttbmeg03#

使用 Integer.toHexString(...) 这是一个很好的答案。但我个人更喜欢用 String.format(...) .
试一下这个样品作为测试。

  1. byte[] values = new byte[64];
  2. Arrays.fill(values, (byte)8); //Fills array with 8 just for test
  3. String valuesStr = "";
  4. for(int i = 0; i < values.length; i++)
  5. valuesStr += String.format("0x%02x", values[i] & 0xff) + " ";
  6. valuesStr.trim();
busg9geu

busg9geu4#

java的parseint方法实际上是一堆吃“false”hex的代码:如果要翻译-32768,应该将绝对值转换为hex,然后在字符串前面加上“-”。
integer.java文件有一个示例:

  1. public static int parseInt(String s, int radix)

描述非常明确:

  1. * Parses the string argument as a signed integer in the radix
  2. * specified by the second argument. The characters in the string
  3. ...
  4. ...
  5. * parseInt("0", 10) returns 0
  6. * parseInt("473", 10) returns 473
  7. * parseInt("-0", 10) returns 0
  8. * parseInt("-FF", 16) returns -255
展开查看全部
sf6xfgos

sf6xfgos5#

值得一提的是,Java8具有 Integer.parseUnsignedInt 以及 Long.parseUnsignedLong 这就是你想要的,特别是: Integer.parseUnsignedInt("ffff8000",16) == -32768 这个名称有点混乱,因为它从十六进制字符串中解析有符号整数,但它确实起作用。

egmofgnx

egmofgnx6#

它溢出了,因为数字是负数。
试试这个,它会起作用的:

  1. int n = (int) Long.parseLong("ffff8000", 16);
t3irkdon

t3irkdon7#

  1. int val = -32768;
  2. String hex = Integer.toHexString(val);
  3. int parsedResult = (int) Long.parseLong(hex, 16);
  4. System.out.println(parsedResult);

这就是你能做到的。
它不能按你的方式工作的原因: Integer.parseInt 需要一个有符号的int,而 toHexString 生成无符号结果。所以如果你插入比 0x7FFFFFF ,将自动抛出错误。如果你把它解析为 long 相反,它仍然会被签署。但当您将它转换回int时,它将溢出到正确的值。

ztigrdn8

ztigrdn88#

以下代码将起作用:

  1. int a=-32768;
  2. String a1=Integer.toHexString(a);
  3. int parsedResult=(int)Long.parseLong(a1,16);
  4. System.out.println("Parsed Value is " +parsedResult);
368yc8dk

368yc8dk9#

尝试使用biginteger类,它可以工作。

  1. int Val=-32768;
  2. String Hex=Integer.toHexString(Val);
  3. //int FirstAttempt=Integer.parseInt(Hex,16); // Error "Invalid Int"
  4. //int SecondAttempt=Integer.decode("0x"+Hex); // Error "Invalid Int"
  5. BigInteger i = new BigInteger(Hex,16);
  6. System.out.println(i.intValue());
mefy6pfw

mefy6pfw10#

呵呵,好奇。可以说,我认为这是一个“内部缺陷”。
根本原因是整数类是如何编写的。基本上,parseint对正数进行了“优化”。当它解析字符串时,它累积地构建结果,但取反。然后它翻转最终结果的符号。
例子:
66=0x42
解析如下:

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

现在,让我们看看您的示例FF8000

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

edit(addition):为了让parseint()对-integer.max\u value<=n<=integer.max\u value“一致地”工作,当累积结果中达到-integer.max\u value时,它们必须实现逻辑来“旋转”,从整数范围的最大端开始,然后从那里继续向下。为什么他们不这样做,人们必须问乔什布洛赫或谁在第一时间实现了它。这可能只是一个优化。
然而,

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

就因为这个原因,一切正常。在integer的sourcee中可以找到此注解。

  1. // Accumulating negatively avoids surprises near MAX_VALUE
展开查看全部

相关问题