【问题标题】:convert a hex string to a binary string in byte throws NumberFormatException将十六进制字符串转换为字节中的二进制字符串会抛出 NumberFormatException
【发布时间】:2013-11-09 09:32:17
【问题描述】:
public static byte[][] keyArray = new byte[4][4]; 
String hex = "93";
String hexInBinary = Integer.toBinaryString(Integer.parseInt(hex, 16));
keyArray[row][col] = Byte.parseByte(hexInBinary,2); //this line causes the error

这是我收到的错误消息,

"Exception in thread "main" java.lang.NumberFormatException: Value out of range. Value:"10010011" Radix:2."

我不想使用 getBytes(),因为我实际上有一个长字符串,“0A935D11496532BC1004865ABDCA42950”。我想一次读取 2 个十六进制并转换为字节。

编辑:

我是如何解决的:

String hexInBinary = String.format("%8s", Integer.toBinaryString(Integer.parseInt(hex, 16))).replace(' ', '0');
keyArray[row][col] = (byte)Integer.parseInt(hexInBinary, 2);

【问题讨论】:

  • 一个字节是有符号的值 -128 到 127。
  • @arshajii: Byte.parseByte("10010011", 2) 对我来说失败了,除了他发布的例外(Java 7)。
  • @vanza 该问题已更新为确实会产生异常的问题。我将删除我的近距离投票。
  • 谢谢大家!我修好了它!!!! Integer.parseInt() 解决了问题!!

标签: java binary hex numberformatexception


【解决方案1】:

正如异常消息中所写,您尝试转换为字节的字符串超过了最大值。一个字节的值可以有。

在您的示例中,字符串“10010011”等于 147,但字节变量的最大值为 2^7 - 1 = 127。

您可能需要查看字节类文档; http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Byte.html#MAX_VALUE

所以我建议使用Integer.parseInt(),而不是parseByte方法,然后将int值转换为字节,整数值147在转换为字节值时将变为-109。

【讨论】:

  • 这并不能真正回答问题。 “10010011”只有 8 位,是一个字节的有效二进制表示(准确地说是 JLS 指定的二进制补码中的 -109)。 API拒绝解析它很奇怪。
  • 为什么不回答问题?我正在解释错误的原因并建议他一个可以正常工作的解决方案。我同意 API 拒绝它很奇怪,但我们现在对此无能为力,如果它不起作用,我们必须找到另一个解决方案。
  • 这不是因为“10010011”是一个有效字节。任何 8 位都是有效字节。您只是提供了一种解决方法。
  • 这个答案的第一行是不正确的。一个字节可以有的最大值是 255。有符号字节可以有的最大值是 127(因为如果最高有效位是 1,那么它被解释为负数)。但是,parseByte 的问题在于它使用显式的“-”符号而不是 1 来表示负数。这意味着“字节”的其余部分只能使用 7 位。
  • 查看我在问题本身的评论中发布的链接。似乎该行为故意与语言规范不一致。 :-/
【解决方案2】:
public class ByteConvert {
    public static void main(String[] argv) {
        String hex = "93";
        String hexInBinary = Integer.toBinaryString(Integer.parseInt(hex, 16));
        int intResult = Integer.parseInt(hexInBinary,2);
        System.out.println("intResult = " + intResult);
        byte byteResult = (byte) (Integer.parseInt(hexInBinary,2));
        System.out.println("byteResult = " + byteResult);
        byte result = Byte.parseByte(hexInBinary,2);
        System.out.println("result = " + result);
    }
}

C:\JavaTools>java ByteConvert
intResult = 147
byteResult = -109
Exception in thread "main" java.lang.NumberFormatException: Value out of range.
Value:"10010011" Radix:2
        at java.lang.Byte.parseByte(Unknown Source)
        at ByteConvert.main(ByteConvert.java:9)

可以看出,parseByte 检测到的值“大于”byte

【讨论】:

    【解决方案3】:

    根据http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Byte.html#parseByte(java.lang.String)的java文档,

     "The characters in the string must all be digits, of the specified radix 
     (as determined by whether Character.digit(char, int) returns a nonnegative
     value) except that the first character may be an ASCII minus 
     sign '-' ('\u002D') to indicate a negative value."
    

    所以二进制表示是不是 twos-compliment。考虑到高位是 1,二进制恭维符号中的字节 10010011 将为负数。因此,如果您想获得与二进制恭维字节 10010011 相同的值,则需要执行 Byte.parseByte("-1101100");

    换句话说,一个无符号字节的最大值是255。一个有符号字节的最大值是127(因为如果最高有效位是1,那么它就是解释为负数)。但是,parseByte() 的问题在于它使用显式的“-”符号而不是 1 来表示负数。这意味着“字节”的其余部分只能使用 7 位。

    【讨论】:

    • 找点乐子:Integer.parseInt(Integer.toBinaryString(-1), 2)。可能与文档一致,但 POLA 失败。
    猜你喜欢
    • 2019-08-23
    • 1970-01-01
    • 2019-07-27
    • 2017-02-23
    • 2014-08-03
    • 2015-06-21
    • 2014-10-24
    • 2012-03-04
    相关资源
    最近更新 更多