1
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

This is the error message I get,

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

I don't want to use getBytes(), because I actually have a long string, "0A935D11496532BC1004865ABDCA42950." I want to read 2 hex at a time and convert to byte.

EDIT:

how I fixed it:

String hexInBinary = String.format("%8s", Integer.toBinaryString(Integer.parseInt(hex, 16))).replace(' ', '0');
keyArray[row][col] = (byte)Integer.parseInt(hexInBinary, 2);
Nayana
  • 1,513
  • 3
  • 24
  • 39
  • http://stackoverflow.com/questions/140131/convert-a-string-representation-of-a-hex-dump-to-a-byte-array-using-java – Sadek Noureddine Oct 30 '13 at 00:19
  • A byte is a signed value -128 to 127. – Hot Licks Oct 30 '13 at 00:25
  • @arshajii: `Byte.parseByte("10010011", 2)` fails for me with the exception he posts (Java 7). – vanza Oct 30 '13 at 00:26
  • @vanza The question has since been updated to something that does produce an exception. I'll remove my close vote. – arshajii Oct 30 '13 at 00:27
  • Thank you everyone! I fixed it!!!! Integer.parseInt() fixed the problem!! – Nayana Oct 30 '13 at 00:41
  • For reference, it seems the API intentionally ignores the [language spec](http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html) :http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4068167 – vanza Oct 30 '13 at 00:48

3 Answers3

1

As it is written in the exception message the string you are trying to convert to byte exceeds the max. value of a byte can have.

In your example the string "10010011" equals to 147, but the max value for a byte variable is 2^7 - 1 = 127.

You might want to check the Byte Class documentation; http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Byte.html#MAX_VALUE

So i suggest to use Integer.parseInt(), instead of parseByte method and then cast the int value to byte, integer value 147 will become -109 when you cast it to byte value.

kerberos84
  • 300
  • 1
  • 10
  • 1
    That doesn't really answer the question. "10010011" has only 8 bits and is a valid binary representation of a byte (-109 in two's complement, which is what the JLS specifies, to be precise). It's weird the API refuses to parse it. – vanza Oct 30 '13 at 00:37
  • How come it does not answer the question? I am explaining the reason of the error and suggesting him a solution which works fine. I agree that it is weird that API refuses it, but we can not do anything about that right now, we have to find another solution if it does not work. – kerberos84 Oct 30 '13 at 00:40
  • 1
    It doesn't because "10010011" is a valid byte. Any 8 bits are a valid byte. You're just providing a work around. – vanza Oct 30 '13 at 00:40
  • The first line of this answer is incorrect. The maximum value a byte can have is 255. The maximum value a *signed* byte can have is 127 (because if the most-significant-bit is 1, then it is interpreted as a negative number). However, the issue with `parseByte` is that it instead uses an explicit "-" symbol instead of a 1 to indicate negative numbers. This means that the rest of the "byte" can only use 7 bits. – Turix Oct 30 '13 at 00:48
  • See link I posted in comment under the question itself. Seems that the behavior is intentionally inconsistent with the language spec. :-/ – vanza Oct 30 '13 at 00:50
  • @kerberos84 This isn't a bug in the JDK given the documentation. (see my answer below) – Turix Oct 30 '13 at 00:51
  • @Turix we are talking about java.Byte class and in its documentation it is said that its max. value is 127. So it is not incorrect. And also i think everyone knows with 8 bit you can store 2^8-1 unsigned values. Anyway thanks for the explanation about that it is not being a bug. – kerberos84 Oct 30 '13 at 00:53
  • When I store the binary string converted into byte, some become negative as you said. I later need to convert them back to hex numbers, does anyone know how to do that? Since some numbers are negative, wouldn't that matter? – Nayana Oct 30 '13 at 00:56
  • @kerberos84 In that case, I would capitalize "byte" to indicate the class "Byte" in the answer to avoid potential misunderstandings. – Turix Oct 30 '13 at 00:57
  • @Turix either we are talking about Byte class or byte primitive type, the maximum value can be stored is 127 in java. So actually there is no misunderstanding unless you are not aware of this topic is about java language. – kerberos84 Oct 30 '13 at 10:31
1
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)

As can be seen, parseByte detects a value "larger" than a byte.

Hot Licks
  • 47,103
  • 17
  • 93
  • 151
0

According to the java documention at http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Byte.html#parseByte(java.lang.String),

 "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."

So the binary representation is not twos-compliment. The byte 10010011 in twos-compliment notation would be negative given that the upper bit is a 1. So if you want to get the same value as the twos-compliment byte 10010011, you would need to do Byte.parseByte("-1101100");.

Put another way, the maximum value an unsigned byte can have is 255. The maximum value a signed byte can have is 127 (because if the most-significant-bit is 1, then it is interpreted as a negative number). However, the issue with parseByte() is that it instead uses an explicit "-" symbol instead of a 1 to indicate negative numbers. This means that the rest of the "byte" can only use 7 bits.

Turix
  • 4,470
  • 2
  • 19
  • 27
  • 1
    For some fun: `Integer.parseInt(Integer.toBinaryString(-1), 2)`. May be consistent with documentation, but fails the [POLA](http://en.wikipedia.org/wiki/Principle_of_least_astonishment). – vanza Oct 30 '13 at 01:49