Java scanner nextInt(16) does not accept negative hex values - java

I need to read in a 32-bit number in hex format. When I enter a negative value, I get an input mismatch exception. Everything works as long as the number is positive (00000000 ~ 7FFFFFFF), but anything negative (80000000 ~ FFFFFFFF) fails.
System.out.println("Enter first number in hexadecimal format: ");
Scanner readX = new Scanner(System.in);
int a = readX.nextInt(16);
I have tried various formats (FFFFFFFF, 0xFFFFFFFF, -FFFFFFFF, -7FFFFFFFF, ~FFFFFFFF) with the same results.
Any ideas? I feel like I must be missing something obvious but I'm completely stumped!

It will fail for the same reason 2147483648 (one more than Integer.MAX_VALUE) will fail for Integer.parseInt: The value is too large. It will not interpret ffffffff or 80000000 as a negative number, but as a large positive number. Those numbers are simply too large to be interpreted as an int.
Scanner.nextInt(int radix) matches a regular expression to see if it could be an int, then it passes it to Integer.parseInt for parsing:
If the next token matches the Integer regular expression defined above then the token is converted into an int value as if by removing all locale specific prefixes, group separators, and locale specific suffixes, then mapping non-ASCII digits into ASCII digits via Character.digit, prepending a negative sign (-) if the locale specific negative prefixes and suffixes were present, and passing the resulting string to Integer.parseInt with the specified radix.
Integer.parseInt will throw a NumberFormatException if it can't be represented as an int:
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.
You must specify the number to be negative. Try -1 or -80000000 or anything in between; they will work.

System.out.println("Enter first number in hexadecimal format: ");
Scanner readX = new Scanner(System.in);
String a = readX.nextLine().trim();
int result = Integer.parseInt(a, 16);
This will be work for youThen you get value as scientific notation if it's not fit to int.

Related

Number Format Exception for Large value

This block of code gives Number Format Exception on input 600000 in n
import java.util.*;
class SpoTwo{
public static void main(String args[]){
Scanner sc=new Scanner(System.in);
int testcase,n,answer;
long bin;
String s;
testcase=sc.nextInt();
for(int i=0;i<testcase;i++){
n=sc.nextInt();
s=Integer.toBinaryString(n);
bin=Integer.parseInt(s);
answer=(int)Math.pow(2,bin*2);
System.out.println(answer%1000000007);
}
}
}
Exception:
Exception in thread "main" java.lang.NumberFormatException: For input string: "10010010011111000000"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:495)
at java.lang.Integer.parseInt(Integer.java:527)
at SpoTwo.main(SpoTwo.java:12)
The binary representation of 600000 is 10010010011111000000. This is not a valid base 10 integer. It is a valid base 2 integer. Use
bin = Integer.parseInt(s, 2);
Here's the method's javadoc.
The overloaded parseInt method you were using
Parses the string argument as a signed decimal integer. The characters
in the string must all be decimal digits, 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, exactly as if
the argument and the radix 10 were given as arguments to the
parseInt(java.lang.String, int) method.
you got a string and move to binary and then converts that string to an integer and then vc is the power, so that the whole supports a certain number of houses, so it's a blast, u can use paserInt putting the number of homes or turns the whole into a double.

java.lang.NumberFormatException: For input string: "10.0"

This code must validate input data from the findActions() method:
try {
System.out.println(findActions(lookingArea.substring(0, right)));// always printing valid number string
Integer.parseInt(findActions(lookingArea.substring(0, right)));// checking for number format
}
catch(NumberFormatException exc) {
System.out.println(exc);
}
But I always have java.lang.NumberFormatException: For input string: "*number*"
that is so strange, because checking with System.out.println(findActions(lookingArea.substring(0, right)));,
I get *number* like 10.0
Integer.parseInt doesn't expect the . character. If you're sure it can be converted to an int, then do one of the following:
Eliminate the ".0" off the end of the string before parsing it, or
Call Double.parseDouble, and cast the result to int.
Quoting the linked Javadocs above:
The characters in the string must all be decimal digits, 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.
10.0 is not an integer number. Instead, you can use:
int num = (int) Double.parseDouble(...);
One of the reason could be that your string is too long to convert into Integer type, So you can declare it as Long or Double based on the provided input.
Long l = Long.parseLong(str);

Java, Long.parse binary String

Why does this code throw a NumberFormatException :
String binStr = "1000000000000000000000000000000000000000000000000000000000000000";
System.out.println(binStr.length());// = 64
System.out.println(Long.parseLong(binStr, 2));
1000000000000000000000000000000000000000000000000000000000000000 is larger than Long.MAX_VALUE.
See https://stackoverflow.com/a/8888969/597657
Consider using BigInteger(String val, int radix) instead.
EDIT:
OK, this is new for me. It appears that Integer.parseInt(binaryIntegerString, 2) and Long.parseLong(binaryLongString, 2) parse binary as sign-magnitude not as a 2's-complement.
Because it's out of range. 1000...000 is 263, but Long only goes up to 263 - 1.
This is the same for all of Long, Integer, Short and Byte. I'll explain with a Byte example because it's readable:
System.out.println(Byte.MIN_VALUE); // -128
System.out.println(Byte.MAX_VALUE); // 127
String positive = "1000000"; // 8 binary digits, +128
String negative = "-1000000"; // 8 binary digits, -128
String plus = "+1000000"; // 8 binary digits, +128
Byte.parseByte(positive, 2); //will fail because it's bigger than Byte.MAX_VALUE
Byte.parseByte(negative, 2); //won't fail. It will return Byte.MIN_VALUE
Byte.parseByte(plus, 2); //will fail because its bigger than Byte.MAX_VALUE
The digits are interpreted unsigned, no matter what radix is provided. If you want a negative value, you have to have the minus sign at the beginning of the String. JavaDoc says:
Parses the string argument as a signed long 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 long value is returned.
In order to get MAX_VALUE we need:
String max = "1111111"; // 7 binary digits, +127
// or
String max2 = "+1111111"; // 7 binary digits, +127
Largest long value is actually:
0111111111111111111111111111111111111111111111111111111111111111b = 9223372036854775807
This is because Long.parseLong cannot parse two's complement representation. The only way to parse two's complement binary string representation in Java SE is BigInteger:
long l = new BigInteger("1000000000000000000000000000000000000000000000000000000000000000", 2).longValue()
this gives expected -9223372036854775808result
This is the largest possible long (9223372036854775807 = 2 exp 63 - 1) in binary format. Note the L at the end of the last digit.
long largestLong = 0B0111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111L;
Actually, this is works for me:
String bitStr = "-1000000000000000000000000000000000000000000000000000000000000000";
System.out.println(Long.parseLong(bitStr, 2));
Here is a thing: inside Long.parseLong() code logic is looking for explicit sign first. And respectively to the sign, different limits are used (Long.MAX_VALUE for positive, and Long.MIN_VALUE for negative binary literals). Probably it would be better if this logic looked up first to the eldest bit (0 for positive and 1 for negative numbers) the sign

NumberFormat Exception to parse String to Byte?

I am trying to parse the following String to Byte.But it gives me NumberFormat Exception.Can some body tell me what is the solution for this?
Byte.parseByte("11111111111111111111111110000001", 2);
Byte.parseByte() handles binary string as sign-magnitude not as a 2's complement, so the longest length you can have for a byte is 7 bits with a sign.
In other words, to represent -127, you should use:
Byte.parseByte("-111111", 2);
The following throws NumberFormatException:
Byte.parseByte("10000000", 2);
However, the binary literal of -127 is:
byte b = (byte) 0b10000000;
The same behavior is applied to the other parseXXX() methods.
Out of range of byte ie -128 to 127. From parseByte(String s,int radix) javadoc:
public static byte parseByte(String s, int radix)throws NumberFormatException
Parses the string argument as a signed byte 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.
The resulting byte 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')
provided that the string is longer than length 1.
The value represented by the string is not a value of type byte.
Returns: the byte value represented by the string argument in the
specified radix Throws: NumberFormatException - If the string does not
contain a parsable byte.
from javadocs
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')
provided that the string is longer than length 1.
The value represented by the string is not a value of type byte.
Your value is the second case that is out of range -128 to 127
Value is too large to be parsed in byte
Try this:
new BigInteger("011111111111111111111111110000001", 2).longValue();

String binary to Hex Java

i have code that looks like this
public static void main(String[] args) {
String string= "11011100010000010001000000000000";
String string1= "00000000010000110000100000101100";
System.out.println(Integer.toHexString(Integer.parseInt(string1,2)));
System.out.println(Integer.toHexString(Integer.parseInt(string,2)));
}
the first string convert just fine but the second one has an error of java.lang.NumberFormatException
dont know what the problem is
try this:
Long.toHexString(Long.parseLong(string,2))
(edited from parsLong to parseLong)
For what's worth, you can also use the BigInteger class :
String string = "11011100010000010001000000000000";
String string1 = "00000000010000110000100000101100";
System.out.println(new BigInteger(string1, 2).toString(16));
System.out.println(new BigInteger(string, 2).toString(16));
When the most significant bit of a 32-character binary number is set to 1, the resultant value exceeds the range of positive numbers supported by int, and can no longer be interpreted as a valid integer number. This causes the exception according to the documentation:
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') provided that the string is longer than length 1.
The value represented by the string is not a value of type int. (emphasis is mine)
In order to enter this negative binary value, use - sign in front of your number, and convert the remaining bits to 2-s complement representation.
If you need numbers that are longer than 32 bits, or if you would like the value to continue being interpreted as a positive number, you would need to switch to the 64-bit integer data type.
You can use Long instead of Integer, (Long.parseLong and Long.toHexString methods).
If you want to parse to integer, the range should be
10000000000000000000000000000000 to 01111111111111111111111111111111

Categories