I want to parse an String containing 8 hex-digits (4bytes) but i got an NumberFormatException. What is wrong here?
assertThat(Integer.parseInt("FFFF4C6A",16),is(0xFFFF4C6A));
Your number represents a number greater than that assignable to an int. Try:
Long.parseLong("FFFF4C6A", 16);
which gives 4294921322.
From the doc:
An exception of type NumberFormatException is thrown if any of the following situations occurs:
The first argument is null or is a string of length zero.
The radix is either smaller than Character.MIN_RADIX or larger than Character.MAX_RADIX.
Any character of the string is not a digit of the specified radix, …
The value represented by the string is not a value of type int.
and it's the 4th case that you're hitting.
You've exceeded the range of an integer.
Integer.MAX_VALUE = 2147483647
0xFFFF4C6A = 4294921322
Parsing it as a Long works:
Long.parseLong("FFFF4C6A",16)
That is because the Integer.parseInt("FFFF4C6A",16) provided exceeds Integer.MAX_VALUE which is defined as public static final int MAX_VALUE = 0x7fffffff;
Now, as per the Javadoc for parseInt(...), you would hit a NumberFormatException in either of the following cases:
An exception of type NumberFormatException is thrown if any of the following situations occurs:
The first argument is null or is a string of length zero.
The radix is either smaller than Character.MIN_RADIX or larger than Character.MAX_RADIX.
Any character of the string is not a digit of the specified radix, except that the first character may be a minus sign '-' ('\u002D') or
plus sign '+' ('\u002B') provided that the string is longer than
length 1.
The value represented by the string is not a value of type int.
In your case, since the String value supplied exceeds Integer.MAX_VALUE, you're satisfying the 4th clause for NumberFormatException
Possible Solution: In order to parse this, use Long.parseLong(...) where the MAX_VALUE is defined as `public static final long MAX_VALUE = 0x7fffffffffffffffL
If you just want to represent that hex string as an integer (since it is 32 bits), you need to use BigInteger:
new BigInteger("FFFF4C6A", 16).intValue()
I don't know the assertThat() method, but your hexadecimal number "FFFF4C6A" is to big for an integer.
For example, if you write :
int number = Integer.parseInt("FFFF4C6A",16)
you'll get the same error.
A correct way to write the code would be :
double number = Integer.parseInt("FFFF4C6A",16)
Related
The following code throws NumberFormatException and I don't understand why,
String sku = "008949679851";
System.out.println(Integer.valueOf(sku));
Interestingly, if I remove the first three digits and the keep the input string as "949679851", then this exception is not thrown. Is there a limit in length when converting a string to an integer value..? How can I make it work with the full string..?
Because the max value of an Integer is Integer.MAX_VALUE = 2147483647 and your number is greater than this 8949679851. Instead use Long.valueOf(sku) or BigInteger for example:
Long l = Long.valueOf(sku);//Max value equal to 9223372036854775807
BigInteger b = new BigInteger(sku);
In Java the maximum value for int and Integers is 2^31-1 (2147483647) so your number exceeds that value.
Java integer size is 32 bits (range -2,147,483,648 to +2,147,483,647). "008949679851" is too long, while "949,679,851" is within the range.
i want to convert hexadecimal value to a signed decimal number.like FFFFFB2E to -1234.Is there any method to do this in java?
Use Long.parseLong by passing 16 as radix of the number that you are entering as below:
long myHexNumber = Long.parseLong("FFFFFB2E", 16);
int number = (int)myHexNumber;
System.out.println(number);
Use Integer.parseInt(String, int), per Java documentation:
Parses the string argument as a signed integer in the radix specified by the second argument. 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 or an ASCII plus sign '+' ('\u002B') to indicate a positive value. The resulting integer value is returned.
An exception of type NumberFormatException is thrown if any of the following situations occurs:
The first argument is null or is a string of length zero.
The radix is either smaller than Character.MIN_RADIX or larger than Character.MAX_RADIX.
Any character of the string is not a digit of the specified radix, except that the first character may be a minus sign '-' ('\u002D') or plus sign '+' ('\u002B') provided that the string is longer than length 1.
The value represented by the string is not a value of type int.
Examples:
parseInt("0", 10) returns 0
parseInt("473", 10) returns 473
parseInt("+42", 10) returns 42
parseInt("-0", 10) returns 0
parseInt("-FF", 16) returns -255
parseInt("1100110", 2) returns 102
parseInt("2147483647", 10) returns 2147483647
parseInt("-2147483648", 10) returns -2147483648
parseInt("2147483648", 10) throws a NumberFormatException
parseInt("99", 8) throws a NumberFormatException
parseInt("Kona", 10) throws a NumberFormatException
parseInt("Kona", 27) returns 411787
I have this code:
private String padWithZeroRightToPeriod(String serverFormat, float unformattedNumber, int index) {
int nDigits = getNumberOfDigitsAfterPeriod(serverFormat);
String floatingFormat = "%4." + nDigits + "f";
String formattedPrice = String.format(floatingFormat, unformattedNumber);
When called with unformattedNumber being 846, why is the result " 846" (a space and then the three digits)?
What does the %4. mean?
The docs for String.format refer you to this documentation on format strings, which says:
The format specifiers for general, character, and numeric types have the following syntax:
%[argument_index$][flags][width][.precision]conversion
The optional argument_index is a decimal integer indicating the position of the argument in the argument list. The first argument is referenced by "1$", the second by "2$", etc.
The optional flags is a set of characters that modify the output format. The set of valid flags depends on the conversion.
The optional width is a positive decimal integer indicating the minimum number of characters to be written to the output.
The optional precision is a non-negative decimal integer usually used to restrict the number of characters. The specific behavior depends on the conversion.
The required conversion is a character indicating how the argument should be formatted. The set of valid conversions for a given argument depends on the argument's data type.
From your example output, it appears that getNumberOfDigitsAfterPeriod is returing 0, so your format string is %4.0f. So:
It doesn't have an argument index (there's no $ after the 4)
It has a width (4)
It has a precision (0)
And of course it has a conversion (f)
So 846 is output as " 846" because the width is 4. The width in question is the total number of characters output. Here's a different example: Live Copy
public class Example {
public static void main(String args[]) {
System.out.println(String.format("%8.2f", 846.0));
System.out.println(String.format("%8.2f", 42.4));
}
}
Output:
846.00
42.40
Note that each of those is eight characters long.
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);
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.
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.
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.
What is the method that you can use to convert between bases in Java? It is something like IntegerToBase (int, base), but I cannot remember.
Literally speaking, integer values are not converted from one base to another. Thanks to von Neumann, one of the pioneers of computing, who thought the idea of trying to use base 10 arithmetic on binary circuitry made little sense, integers are stored in binary format and we are not trying to change that :-) What we are talking about is converting them to strings representing them in some base (other that base 10 which is the default) and converting strings to integers in bases other than (the default) base 10. The necessary tools are static methods of the Integer class.
Java provides the Integer.toString(int i, int radix) conversion function which takes an integer and a radix (the base) and returns that integer's string representation in that base.
String hexRepr = Integer.toString(255, 16) // returns "FF"
To go the other way around, i.e. from a string representing a number in a different base there is Integer.parseInt(String s, int radix)
int myNum = Integer.parseInt("FF", 16) // returns 255
To convert a number represented as a base radix1 string to a base radix2 string representation the two methods just mentioned have to be combined as the following examples shows:
int radix1 = 16; // The input will be parsed assuming base 16 representation
int radix2 = 4; // The result will be output using a base 4 representation
String input = "FF"; // which in base 16 represents the number 255
String converted = Integer.toString(Integer.parseInt(radix1Representation, radix1),radix2); /// returns "3333" which in base 4 is the number 255
More details can be found in the API documentation. I have included some of it here, to ensure readers also see the things they need to be careful with when using these methods.
public static String toString(int i, int radix)
This method returns a string representation of the first argument in the radix specified by the second argument.
If the radix is smaller than Character.MIN_RADIX or larger than Character.MAX_RADIX, then the radix 10 is used instead.
If the first argument is negative, the first element of the result is the ASCII minus character '-' ('\u002D'). If the first argument is not negative, no sign character appears in the result.
The remaining characters of the result represent the magnitude of the first argument. If the magnitude is zero, it is represented by a single zero character '0' ('\u0030'); otherwise, the first character of the representation of the magnitude will not be the zero character. The following ASCII characters are used as digits:
0123456789abcdefghijklmnopqrstuvwxyz
These are '\u0030' through '\u0039' and '\u0061' through '\u007A'. If radix is N, then the first N of these characters are used as radix-N digits in the order shown. Thus, the digits for hexadecimal (radix 16) are 0123456789abcdef. If uppercase letters are desired, the String.toUpperCase() method may be called on the result:
Integer.toString(n, 16).toUpperCase()
Source: http://docs.oracle.com/javase/7/docs/api/java/lang/Integer.html#toString%28int,%20int%29
public static int parseInt(String s, int radix) throws NumberFormatException
This method parses the string argument as a signed integer in the radix specified by the second argument. 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 or an ASCII plus sign '+' ('\u002B') to indicate a positive value. The resulting integer value is returned.
An exception of type NumberFormatException is thrown if any of the following situations occurs:
The first argument is null or is a string of length zero.
The radix is either smaller than Character.MIN_RADIX or larger than Character.MAX_RADIX.
Any character of the string is not a digit of the specified radix, except that the first character may be a minus sign '-' ('\u002D') or plus sign '+' ('\u002B') provided that the string is longer than length 1.
The value represented by the string is not a value of type int.
Examples:
parseInt("0", 10) // returns 0
parseInt("473", 10) // returns 473
parseInt("+42", 10) // returns 42
parseInt("-0", 10) // returns 0
parseInt("-FF", 16) // returns -255
parseInt("1100110", 2) // returns 102
parseInt("2147483647", 10) // returns 2147483647
parseInt("-2147483648", 10) // returns -2147483648
parseInt("2147483648", 10) // throws NumberFormatException
parseInt("99", 8) // throws NumberFormatException
parseInt("Kona", 10) // throws NumberFormatException
parseInt("Kona", 27) // returns 411787
Source: http://docs.oracle.com/javase/7/docs/api/java/lang/Integer.html#parseInt%28java.lang.String,%20int%29
The Integer class offers two utility methods which offer this functionality, although strings are the medium of conversion:
Integer.parseInt(String s, int radix) to parse from a given base
Integer.toString(int i, int radix) to convert to a given base
Note that Integer internally stores values in decimal form (base 10).
For example, to convert 01000 (octal) to 512 (decimal) and back, you can do the following:
String octal = "01000";
int i = Integer.parseInt(octal, 8);
String decimal = Integer.toString(i, 10);
System.out.println(decimal); // prints 512
You can use Integer.parseInt("101", 2) for example, it will give you 5 (correspond decimal number).
Returns an Integer object holding the value extracted from the
specified String when parsed with the radix given by the second
argument. The first argument is interpreted as representing a signed
integer in the radix specified by the second argument, exactly as if
the arguments were given to the parseInt(java.lang.String, int)
method. The result is an Integer object that represents the integer
value specified by the string. In other words, this method returns an
Integer object equal to the value of: (source)
new Integer(Integer.parseInt(s, radix))
From the same source, you also have:
public static String toString(int i,int radix)
Returns a string representation of the first argument in the radix specified by the second argument.
So if you want to convert from binary to decimal:
Integer.parseInt(binary_number_in_string, 2);
if you want from decimal to binary:
System.out.println(Integer.toString(2,2));
To convert from another base to decimal and vise versa you just have to change the radix parameter.
Note that the class Integer have already some default conversation methods, such as:
public static String toBinaryString(int i)
Returns a string representation of the integer argument as an unsigned integer in base 2
(source).
public static String toHexString(int i)
Returns a string representation of the integer argument as an unsigned integer in base 16 (source).
public static String toOctalString(int i)
Returns a string representation of the integer argument as an unsigned
integer in base 8 (source).
As you can see from the return type of the above methods, it is not the integer that are being convert between base. The methods are returning the String representation in a give base of the integer pass as a argument.