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
Related
I am developing an application in Android using Eclipse. I wrote the following code and in tests the first and third "if" block is not reachable. Why?
When I add a leading zero to a number, the equal operator returns false.
int var = 123;
if (var == 0123) {
//not reachable
}
if (var == 123) {
//reachable
}
if (var == (int)0123) {
//not reachable
}
if (var == (int)123) {
//reachable
}
0123 is an octal number (leading 0), while 123 is a decimal number.
so 0123 actually equals to 83.
Any integer Number Leading With Zero is octal Number (base 8).
0123 is octal Number and 123 is Decimal Number
0123 = (3*8^0) +(2*8^1)+(1*8^2)+(0*8^4)
=3+16+64+0
=83
because 0123 in not decimal digit its octal (base 8)
so this is equal to 83
To convert a number k to decimal, use the formula that defines its base-8 representation:
0123 base-8 = 83 decimal
0123 = (3*8^0) +(2*8^1)+(1*8^2)+(0*8^4)
=3+16+64+0
=83
An octal numeral consists of an ASCII digit 0 followed by one or more of the ASCII digits 0 through 7 and can represent a positive, zero, or negative integer.
Note: Octal values are denoted in java by leading zero normal decimal number cannot have a leading zero
I am missing something while determining how Java stores and retrieves integers. I have the following code
public class Test1 {
public static void main(String args[]) {
int a = 100;
int negateA = (a | 0x80000000);
System.out.println("Negative A: " + negateA);
System.out.println("Negative A in HEX: " + Integer.toHexString(negateA));
}
}
Output:
Negative A: -2147483548
Negative A in HEX: 80000064
From the output, the value in HEX makes sense to me as I am setting the most significant bit of the integer and the rest of the value indicates its decimal value to be 100 which is what I 've set it initially.
I fail to understand why when I print just the integer I get -2147483548
Is there a difference between how java stores the number internally and when its retrieved?
This is not how you obtain a negative number from a positive number! Java uses two's complement.
In order to invert the sign of an int (whether it is initally positive or negative), you do:
~val + 1
Same for longs, bytes and shorts.
The only number for which it doesn't work is 0x80000000, ie Integer.MIN_VALUE, ie -2^31. But that is one of the characteristics of an n-bit two's complement representation: it can represent numbers ranging from -2^(n-1) up to 2^(n-1) - 1.
Let's take 1 as an example:
0x00000001 // i = 1
0xFFFFFFFE // ~i
0xFFFFFFFF // ~i + 1 == -1
0xFFFFFFFF // i = -1
0x00000000 // ~i
0x00000001 // ~i + 1 == 1
The difference is not between "how it is stored" and "when it is retrieved", but it boils down to how the internal representation is interpreted when you convert to decimal and binary. In the first case it is interpreted as twos-complement, which yields your negative number. When you convert it to hex using Integer.toHexString, it is intepreted as an unsigned value. From the javadoc of Integer.toHexString:
The unsigned integer value is the argument plus 23^2 if the argument is
negative; otherwise, it is equal to the argument
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.
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)