java.lang.NumberFormatException in my binary progam - java

I'm really new to Java so excuse my ignorance, but I cannot figure out why my program keeps throwing an error every single time. I'm making a program that converts a string into binary and back. Here's my error. I've tried all sorts of different methods but it always throws the same error. :(
Exception in thread "main" java.lang.NumberFormatException: For input string: "010000010001011110010000000010001000"
at java.lang.NumberFormatException.forInputString(Unknown Source)
at java.lang.Integer.parseInt(Unknown Source)
at main.main(main.java:64)
Here's my line of code.
int charCode = Integer.parseInt(String.valueOf(binary), 2);
Binary is used with StringBuilder if you were wondering.
Thanks in advance! :)
PS I did try and find similar problems such as mine but to no avail.

Try:
long charCode = Long.parseLong(String.valueOf(binary), 2);
Your binary value more than Integer.MAX_VALUE

Integer in Java (and almost all other programming languages) is 4 bytes long, it means it can only stores ~4 300 000 000 numbers, with negative numbers, it is ~ -2 147 000 000 to +2 147 000 000
Number you are inputing is just too big for parsing it into Integer.
Also I do not see any reason why you should parse binary code into integer. This should do the trick:
String binaryInput = "10000010001011110010000000010001000";
long myNumber = 0;
for (int i = binaryInput.length()-1; i >= 0; i--) {
if (binaryInput.charAt(i) == '1') {
myNumber += Math.pow(2, binaryInput.length() - i - 1);
}
}
System.out.println("And the value is: " + myNumber);
Output:
And the value is: 17473011848

How about BigInteger with base '2' ?? Single line of code....
String str = "010000010001011110010000000010001000";
System.out.println(new BigInteger(str, 2));

Related

Convert android ID hex to decimal [duplicate]

I have the following code...
int Val=-32768;
String Hex=Integer.toHexString(Val);
This equates to ffff8000
int FirstAttempt=Integer.parseInt(Hex,16); // Error "Invalid Int"
int SecondAttempt=Integer.decode("0x"+Hex); // Error "Invalid Int"
So, initially, it converts the value -32768 into a hex string ffff8000, but then it can't convert the hex string back into an Integer.
In .Net it works as I'd expect, and returns -32768.
I know that I could write my own little method to convert this myself, but I'm just wondering if I'm missing something, or if this is genuinely a bug?
int val = -32768;
String hex = Integer.toHexString(val);
int parsedResult = (int) Long.parseLong(hex, 16);
System.out.println(parsedResult);
That's how you can do it.
The reason why it doesn't work your way: Integer.parseInt takes a signed int, while toHexString produces an unsigned result. So if you insert something higher than 0x7FFFFFF, an error will be thrown automatically. If you parse it as long instead, it will still be signed. But when you cast it back to int, it will overflow to the correct value.
It overflows, because the number is negative.
Try this and it will work:
int n = (int) Long.parseLong("ffff8000", 16);
int to Hex :
Integer.toHexString(intValue);
Hex to int :
Integer.valueOf(hexString, 16).intValue();
You may also want to use long instead of int (if the value does not fit the int bounds):
Hex to long:
Long.valueOf(hexString, 16).longValue()
long to Hex
Long.toHexString(longValue)
It's worth mentioning that Java 8 has the methods Integer.parseUnsignedInt and Long.parseUnsignedLong that does what you wanted, specifically:
Integer.parseUnsignedInt("ffff8000",16) == -32768
The name is a bit confusing, as it parses a signed integer from a hex string, but it does the work.
Try using BigInteger class, it works.
int Val=-32768;
String Hex=Integer.toHexString(Val);
//int FirstAttempt=Integer.parseInt(Hex,16); // Error "Invalid Int"
//int SecondAttempt=Integer.decode("0x"+Hex); // Error "Invalid Int"
BigInteger i = new BigInteger(Hex,16);
System.out.println(i.intValue());
As Integer.toHexString(byte/integer) is not working when you are trying to convert signed bytes like UTF-16 decoded characters you have to use:
Integer.toString(byte/integer, 16);
or
String.format("%02X", byte/integer);
reverse you can use
Integer.parseInt(hexString, 16);
Java's parseInt method is actally a bunch of code eating "false" hex : if you want to translate -32768, you should convert the absolute value into hex, then prepend the string with '-'.
There is a sample of Integer.java file :
public static int parseInt(String s, int radix)
The description is quite explicit :
* Parses the string argument as a signed integer in the radix
* specified by the second argument. The characters in the string
...
...
* parseInt("0", 10) returns 0
* parseInt("473", 10) returns 473
* parseInt("-0", 10) returns 0
* parseInt("-FF", 16) returns -255
Using Integer.toHexString(...) is a good answer. But personally prefer to use String.format(...).
Try this sample as a test.
byte[] values = new byte[64];
Arrays.fill(values, (byte)8); //Fills array with 8 just for test
String valuesStr = "";
for(int i = 0; i < values.length; i++)
valuesStr += String.format("0x%02x", values[i] & 0xff) + " ";
valuesStr.trim();
Below code would work:
int a=-32768;
String a1=Integer.toHexString(a);
int parsedResult=(int)Long.parseLong(a1,16);
System.out.println("Parsed Value is " +parsedResult);
Hehe, curious. I think this is an "intentianal bug", so to speak.
The underlying reason is how the Integer class is written. Basically, parseInt is "optimized" for positive numbers. When it parses the string, it builds the result cumulatively, but negated. Then it flips the sign of the end-result.
Example:
66 = 0x42
parsed like:
4*(-1) = -4
-4 * 16 = -64 (hex 4 parsed)
-64 - 2 = -66 (hex 2 parsed)
return -66 * (-1) = 66
Now, let's look at your example
FFFF8000
16*(-1) = -16 (first F parsed)
-16*16 = -256
-256 - 16 = -272 (second F parsed)
-272 * 16 = -4352
-4352 - 16 = -4368 (third F parsed)
-4352 * 16 = -69888
-69888 - 16 = -69904 (forth F parsed)
-69904 * 16 = -1118464
-1118464 - 8 = -1118472 (8 parsed)
-1118464 * 16 = -17895552
-17895552 - 0 = -17895552 (first 0 parsed)
Here it blows up since -17895552 < -Integer.MAX_VALUE / 16 (-134217728).
Attempting to execute the next logical step in the chain (-17895552 * 16)
would cause an integer overflow error.
Edit (addition): in order for the parseInt() to work "consistently" for -Integer.MAX_VALUE <= n <= Integer.MAX_VALUE, they would have had to implement logic to "rotate" when reaching -Integer.MAX_VALUE in the cumulative result, starting over at the max-end of the integer range and continuing downwards from there. Why they did not do this, one would have to ask Josh Bloch or whoever implemented it in the first place. It might just be an optimization.
However,
Hex=Integer.toHexString(Integer.MAX_VALUE);
System.out.println(Hex);
System.out.println(Integer.parseInt(Hex.toUpperCase(), 16));
works just fine, for just this reason. In the sourcee for Integer you can find this comment.
// Accumulating negatively avoids surprises near MAX_VALUE

To check if hex string is in given range [duplicate]

I have the following code...
int Val=-32768;
String Hex=Integer.toHexString(Val);
This equates to ffff8000
int FirstAttempt=Integer.parseInt(Hex,16); // Error "Invalid Int"
int SecondAttempt=Integer.decode("0x"+Hex); // Error "Invalid Int"
So, initially, it converts the value -32768 into a hex string ffff8000, but then it can't convert the hex string back into an Integer.
In .Net it works as I'd expect, and returns -32768.
I know that I could write my own little method to convert this myself, but I'm just wondering if I'm missing something, or if this is genuinely a bug?
int val = -32768;
String hex = Integer.toHexString(val);
int parsedResult = (int) Long.parseLong(hex, 16);
System.out.println(parsedResult);
That's how you can do it.
The reason why it doesn't work your way: Integer.parseInt takes a signed int, while toHexString produces an unsigned result. So if you insert something higher than 0x7FFFFFF, an error will be thrown automatically. If you parse it as long instead, it will still be signed. But when you cast it back to int, it will overflow to the correct value.
It overflows, because the number is negative.
Try this and it will work:
int n = (int) Long.parseLong("ffff8000", 16);
int to Hex :
Integer.toHexString(intValue);
Hex to int :
Integer.valueOf(hexString, 16).intValue();
You may also want to use long instead of int (if the value does not fit the int bounds):
Hex to long:
Long.valueOf(hexString, 16).longValue()
long to Hex
Long.toHexString(longValue)
It's worth mentioning that Java 8 has the methods Integer.parseUnsignedInt and Long.parseUnsignedLong that does what you wanted, specifically:
Integer.parseUnsignedInt("ffff8000",16) == -32768
The name is a bit confusing, as it parses a signed integer from a hex string, but it does the work.
Try using BigInteger class, it works.
int Val=-32768;
String Hex=Integer.toHexString(Val);
//int FirstAttempt=Integer.parseInt(Hex,16); // Error "Invalid Int"
//int SecondAttempt=Integer.decode("0x"+Hex); // Error "Invalid Int"
BigInteger i = new BigInteger(Hex,16);
System.out.println(i.intValue());
As Integer.toHexString(byte/integer) is not working when you are trying to convert signed bytes like UTF-16 decoded characters you have to use:
Integer.toString(byte/integer, 16);
or
String.format("%02X", byte/integer);
reverse you can use
Integer.parseInt(hexString, 16);
Java's parseInt method is actally a bunch of code eating "false" hex : if you want to translate -32768, you should convert the absolute value into hex, then prepend the string with '-'.
There is a sample of Integer.java file :
public static int parseInt(String s, int radix)
The description is quite explicit :
* Parses the string argument as a signed integer in the radix
* specified by the second argument. The characters in the string
...
...
* parseInt("0", 10) returns 0
* parseInt("473", 10) returns 473
* parseInt("-0", 10) returns 0
* parseInt("-FF", 16) returns -255
Using Integer.toHexString(...) is a good answer. But personally prefer to use String.format(...).
Try this sample as a test.
byte[] values = new byte[64];
Arrays.fill(values, (byte)8); //Fills array with 8 just for test
String valuesStr = "";
for(int i = 0; i < values.length; i++)
valuesStr += String.format("0x%02x", values[i] & 0xff) + " ";
valuesStr.trim();
Below code would work:
int a=-32768;
String a1=Integer.toHexString(a);
int parsedResult=(int)Long.parseLong(a1,16);
System.out.println("Parsed Value is " +parsedResult);
Hehe, curious. I think this is an "intentianal bug", so to speak.
The underlying reason is how the Integer class is written. Basically, parseInt is "optimized" for positive numbers. When it parses the string, it builds the result cumulatively, but negated. Then it flips the sign of the end-result.
Example:
66 = 0x42
parsed like:
4*(-1) = -4
-4 * 16 = -64 (hex 4 parsed)
-64 - 2 = -66 (hex 2 parsed)
return -66 * (-1) = 66
Now, let's look at your example
FFFF8000
16*(-1) = -16 (first F parsed)
-16*16 = -256
-256 - 16 = -272 (second F parsed)
-272 * 16 = -4352
-4352 - 16 = -4368 (third F parsed)
-4352 * 16 = -69888
-69888 - 16 = -69904 (forth F parsed)
-69904 * 16 = -1118464
-1118464 - 8 = -1118472 (8 parsed)
-1118464 * 16 = -17895552
-17895552 - 0 = -17895552 (first 0 parsed)
Here it blows up since -17895552 < -Integer.MAX_VALUE / 16 (-134217728).
Attempting to execute the next logical step in the chain (-17895552 * 16)
would cause an integer overflow error.
Edit (addition): in order for the parseInt() to work "consistently" for -Integer.MAX_VALUE <= n <= Integer.MAX_VALUE, they would have had to implement logic to "rotate" when reaching -Integer.MAX_VALUE in the cumulative result, starting over at the max-end of the integer range and continuing downwards from there. Why they did not do this, one would have to ask Josh Bloch or whoever implemented it in the first place. It might just be an optimization.
However,
Hex=Integer.toHexString(Integer.MAX_VALUE);
System.out.println(Hex);
System.out.println(Integer.parseInt(Hex.toUpperCase(), 16));
works just fine, for just this reason. In the sourcee for Integer you can find this comment.
// Accumulating negatively avoids surprises near MAX_VALUE

How to store a long value in java dynamically?

I was solving a problem on a competitive coding website in java. My code for the problem is:
long arr[]=new long[1000001];
for(int i=2;i<=1000000;i++)
{
arr[i]=arr[i-1]+(i*(i-1));
}
int Test = Integer.parseInt(br.readLine());
for (int i = 0; i < Test; i++) {
int num=Integer.parseInt(br.readLine());
System.out.println(arr[num]);
}
Input
3
1
2
3
4
It is showing correct output as:
0
2
8
20
But when the input is like:
3
10000
100000
1000000
It is showing as:
333333330000
18108503577376
16881588911936
but the output should be:
333333330000
333333333300000
333333333333000000
the last two is wrong.I tried using BigInteger but the time gets exceeded.
However I solved it in python 2.7:
a=[]
a.append(0)
a.append(0)
for i in range(2,1000001):
a.append(a[i-1]+(i*(i-1)));
t=input()
while t:
t-=1
print a[input()]
Input:
Input
3
10000
100000
1000000
Output
333333330000
333333333300000
333333333333000000
Someone please help me how to solve this in Java.
Why is it not showing correct output even if the answer fits into a long?
You're doing most of your calculation with ints, not longs:
arr[i]=arr[i-1]+(i*(i-1));
// ^^^^^^^^^------ All of this is with `int`s
So it overflows the int range before being converted to a long when you add it to arr[i-1].
To avoid overflow, you'll want to cast so you're working with longs earlier:
arr[i]=arr[i-1]+((long)i*(i-1));
// ^^^^^^
Live example

How to cast String with decimal(a.bc) to int(abc) in Java

I want to do some calculation with a list of String:
1.23
4.56
7.89
For accuracy, I want the convert the above String to int:
123
456
789
How to do that?
Sorry for my vague description. What I really need is no matter what the input is, the int value should hold the specific decimal:
Let say I need 4 decimal:
String:1 ; int: 10000
String:1.23 int: 12300
String:1.2345 int:12345
I would strip out the dots then parse as an int:
int i = Integer.parseInt(str.replace(".", ""));
If you need there to always be 3 digits, this approach gets ugly, but doable:
int i = Integer.parseInt((str.replace(".", "") + "00").replaceAll("^(...).*", "$1"));
This avoids the vagaries of the imprecision of double values, which could lead to incorrect results due to truncation when casting from double to int.
Here's an example of imprecision problems:
int i = (int) (100 * Double.parseDouble("1.13")); // 112
This is because:
double d = Double.parseDouble("1.13"); // 112.99999999999999
You can use
long n = Math.round(Double.parseDouble(text) * 100);
This will mean numbers like 0.1 will be 10 not 1 and 1.110 will be 111 not 1110
Let say I need 4 decimal:
String:1 ; int: 10000
String:1.23 int: 12300
String:1.2345 int:12345
needs
long n = Math.round(Double.parseDouble(text) * 10000);
You can replace all dots with empty strings (text.replace(".", "")) and then use Integer.parseInt(text).
For one String, you can do:
private static final BigDecimal ONE_HUNDRED
= new BigDecimal(100);
// In code:
new BigDecimal(inputString).multiply(ONE_HUNDRED).intValueExact();
Note the use of BigDecimal here; a double will NOT do.
Note also that it will work only if the input has at most two decimal digits: if more than that, .intValueExact() will throw an exception (it will also throw an exception if the decimal integer is out of bounds for an int).
Now, it depends on how precise you need to be; this method guarantees the results. The method to remove dots and parse as int is obviously faster ;)
I will suggest you use string.replace and replace all "." with "". Then you can use Integer.parseInt(str) and you will have the result.
str = str.replace(".", "");
int val = Integer.parseInt(str);

XOR hex ascii values of letters

I'm trying to complete some homework and am totally stumped. The function I need to perform is, given the hexadecimal value of a character, xor it with another hex value to verify a known end value.
Giving a simple example (the one given to me), I know that the ascii value of 'Bob' would be [42,6F,62], and 'Eve' would be [45,76,65]. I have to XOR 'Bob''s value with [07,16,17] to get 'Eve'.
I thought that xor was simply addition modulo base, but simply using the Microsoft Calculator: (42 + 45) mod 16 = 3 but 42 XOR 45 = 7. I do not understand how else the XOR function would be done. Can someone please explain?
Thanks in advance
I tried
float l = (6F)^(16);
System.out.println(l);
and got this exception:
Exception in thread "main" java.lang.RuntimeException: Uncompilable source code - bad operand types for binary operator '^'
first type: float
second type: double
at p2p_example.P2P_Example.main(P2P_Example.java:40)
Java Result: 1
XOR is a bitwise exclusive-or,
42 = 1000010
45 = 1000101
7 = 0000111
That is a one if there is one (and only one) one in the two bits being XORd. For Java, you can use parseInt and pass in the radix, for example
public static void main(String[] args) {
int a = Integer.parseInt("42", 16);
int b = Integer.parseInt("45", 16);
System.out.println(Integer.toString(a ^ b, 16));
}
prints
7
0x42 + 0x45 = 0x87
= 135
135 % 16 = 7 = 0x07
I think you're getting confused between hex and decimal bases (though (42+45)%16 also happens to be 7 in decimal; so maybe you're just doing your math wrong?)

Categories

Resources