The goal is to convert a String to int in java.
My declarations:
String [] dataIn = new String[100];
int [] binVals = new int[100];
int i;
String toBinary;
I first convert a hex string to a binary string.
static String hexToBin(String s) {
return new BigInteger(s,16).toString(2);
}
.....
.....
toBinary = hexToBin(dataIn[i]);
try{
int temp = Integer.parseInt(toBinary);
binVals[i] = temp;
System.out.println(temp);
} catch (NumberFormatException ex){
System.out.println("Not gonna work");
}
toBinary is a String value of 32 bits i.e. 00011100...01
I printed the result to the console to make sure it is valid for an integer conversion. Yet, using Integer.parseInt(toBinary); still throws the exception. What am I missing here?
Updated
According to what you guys said, I now no longer receive an exception, but when I convert the binary String into an integer, it seems to become a decimal integer.
if (i % 2 == 0)
{
toBinary = hexToBin(dataIn[i]);
System.out.println("Binary in String: " + toBinary);
try{
int temp = Integer.parseInt(toBinary, 2);
binVals[i] = temp;
System.out.println("binVals[i] in int" + binVals[i]);
} catch (NumberFormatException ex){
System.out.println("Not gonna work");
}
//System.out.println(temp);
} else {
System.out.println("This should be a timestamp: " + dataIn[i]);
}
Output:
Binary in String: 1001010101010101010101010100000
binVals[i] in int1252698784
This should be a timestamp: 2068a40
The problem is that Integer.parseInt without a radix will interpret the string as a decimal number, not binary. Most such "binary" strings will represent numbers that are over the maximum integer possible, a little over 2 billion, e.g. 111,000,101,010,001.
Pass in a radix of 2 (binary) to Integer.parseInt:
int temp = Integer.parseInt(toBinary, 2);
However, if the first "bit" is set, then the represented number will be over Integer.MAX_VALUE, and then only Long.parseLong will work.
Try Integer.parseInt(toBinary, 2);. the 2 specifies that the string is in binary (base 2)
Edit: for your new issue, the problem is that Java will by default print integers as decimal, so you need to turn your (decimal) integer back into a binary string. You can use Integer.toBinaryString(int i) for this.
For parsing and formatting integers you should consider using BigInteger.
Converting to String in any radix use BigInteger.toString(int radix).
For parsing use new BigInteger(String s, int radix).
Related
I'm learning JAVA and recently I had the same problem with a few training tasks.
I have a some numbers and some of them are starting with 0. I found out that these numbers are octal which means it won't be the number I wanted or it gives me an error (because of the "8" or the "9" because they are not octal digits) after I read it as an int or long...
Until now I only had to work with two digit numbers like 14 or 05.
I treated them as Strings and converted them into numbers with a function that checks all of the String numbers and convert them to numbers like this
String numStr = "02";
if(numStr.startsWith("0")) {
int num = getNumericValue(numStr.charAt(1));
} else {
int num = Integer.parseInt(numStr);
}
Now I have an unkown lot of number with an unknown number of digits (so maybe more than 2). I know that if I want I can use a loop and .substring(), but there must be an easier way.
Is there any way to simply ignore the zeros somehow?
Edit:
Until now I always edited the numbers I had to work with to be Strings because I couldn't find an easier way to solve the problem. When I had 0010 27 09 I had to declare it like:
String[] numbers = {"0010", "27", "09"};
Because if I declare it like this:
int[] numbers = {0010, 27, 09};
numbers[0] will be 8 instead of 10 and numbers[2] will give me an error
Actually I don't want to work with Strings. What I actually want is to read numbers starting with zero as numbers (eg.: int or long) but I want them to be decimal. The problem is that I have a lot of number from a source. I copied them into the code and edited it to be a declaration of an array. But I don't want to edit them to be Strings just to delete the zeros and make them numbers again.
I'm not quite sure what you want to achieve. Do you want to be able to read an Integer, given as String in a 8-based format (Case 1)? Or do you want to read such a String and interpret it as 10-based though it is 8-based (Case 2)?
Or do you simply want to know how to create such an Integer without manually converting it (Case 3)?
Case 1:
String input = "0235";
// Cut the indicator 0
input = input.substring(1);
// Interpret the string as 8-based integer.
Integer number = Integer.parseInt(input, 8);
Case 2:
String input = "0235";
// Cut the indicator 0
input = input.substring(1);
// Interpret the string as 10-based integer (default).
Integer number = Integer.parseInt(input);
Case 3:
// Java interprets this as octal number
int octal = 0235;
// Java interprets this as hexadecimal number
int hexa = 0x235
// Java interprets this as decimal number
int decimal = 235
You can expand Case 1 to a intelligent method by reacting to the indicator:
public Integer convert(final String input) {
String hexaIndicator = input.substring(0, 2);
if (hexaIndicator.equals("0x")) {
return Integer.parseInt(input.substring(2), 16);
} else {
String octaIndicator = input.substring(0, 1);
if (octaIndicator.equals("0")) {
return Integer.parseInt(input.substring(1), 8);
} else {
return Integer.parseInt(input);
}
}
}
Below is a snippet of my java code.
//converts a binary string to hexadecimal
public static String binaryToHex (String binaryNumber)
{
BigInteger temp = new BigInteger(binaryNumber, 2);
return temp.toString(16).toUpperCase();
}
If I input "0000 1001 0101 0111" (without the spaces) as my String binaryNumber, the return value is 957. But ideally what I want is 0957 instead of just 957. How do I make sure to pad with zeroes if hex number is not 4 digits?
Thanks.
You do one of the following:
Manually pad with zeroes
Use String.format()
Manually pad with zeroes
Since you want extra leading zeroes when shorter than 4 digits, use this:
BigInteger temp = new BigInteger(binaryNumber, 2);
String hex = temp.toString(16).toUpperCase();
if (hex.length() < 4)
hex = "000".substring(hex.length() - 1) + hex;
return hex;
Use String.format()
BigInteger temp = new BigInteger(binaryNumber, 2);
return String.format("%04X", temp);
Note, if you're only expecting the value to be 4 hex digits long, then a regular int can hold the value. No need to use BigInteger.
In Java 8, do it by parsing the binary input as an unsigned number:
int temp = Integer.parseUnsignedInt(binaryNumber, 2);
return String.format("%04X", temp);
The BigInteger becomes an internal machine representation of whatever value you passed in as a String in binary format. Therefore, the machine does not know how many leading zeros you would like in the output format. Unfortunately, the method toString in BigInteger does not allow any kind of formatting, so you would have to do it manually if you attempt to use the code you showed.
I customized your code a bit to include leading zeros based on input string:
public static void main(String[] args) {
System.out.println(binaryToHex("0000100101010111"));
}
public static String binaryToHex(String binaryNumber) {
BigInteger temp = new BigInteger(binaryNumber, 2);
String hexStr = temp.toString(16).toUpperCase();
int b16inLen = binaryNumber.length()/4;
int b16outLen = hexStr.length();
int b16padding = b16inLen - b16outLen;
for (int i=0; i<b16padding; i++) {
hexStr=('0'+hexStr);
}
return hexStr;
}
Notice that the above solution counts up the base16 digits in the input and calculates the difference with the base16 digits in the output. So, it requires the user to input a full '0000' to be counted up. That is '000 1111' will be displayed as 'F' while '0000 1111' as '0F'.
I am trying to get the last two and first two digits from a number. I am getting a really weird result with the return value of my lastTwo function.
public static int lastTwo(int digit){
String str = Integer.toString(digit);
String lastTwo = str.substring(str.length()-2);
int response = Integer.parseInt(lastTwo);
return response;
}
When the input digit is 104, the output of this is just 4, but when the input is 114, the output is 14 which is the correct output. Why is substring on 104 not returning a 0 in the correct place?
here is my bluej console just for extra visuals:
twoDigit.main({ }) (104)
4
10
twoDigit.main({ }) (114)
14
10
Your code is doing the splitting correctly, but primitive ints are not stored with leading zeroes; you can just return the String instead of Integer.parseing it back to an int. e.g.
public static int lastTwoAsString(int digit){
String str = Integer.toString(digit);
String lastTwo = str.substring(str.length()-2);
return lastTwo;
}
If you indeed want to parse it back to an int, Java won't print leading zeroes by default. However, you can print leading zeroes of an int using use String.format. Note that you must specify a width to use the 0 modifier, in this case 2 makes the most sense:
public static void main(String[] args) {
int value = lastTwo(104);
String output = String.format("%02d", value);
System.out.println(output);
}
Output:
04
The last two digits of "104" is "04".
Then, the result of Integer.parseInt("04") is 4, because as an integer, the value of "04" is simply 4. And if you print the number 4, it's naturally printed as "4".
But why do you call Integer.parseInt at all?
The problem description seems underspecified.
It's not clear if the last two digits should be treated as a number or as a string.
If the last two digits should be a string, then your method should return a string.
If the last two digits should be a number, then instead of converting the input int to a String, it would be better to use the modulo operator:
static int lastTwo(int number) {
return number % 100;
}
static String lastTwoAsString(int number) {
String string = Integer.toString(number);
return string.substring(string.length() - 2);
}
The current method signature returns an int. As such, it cannot return 02. You will have to change it to String or format the output where the method is called.
If you can change the return type to String, you can do:
First way:
public static String lastTwo(int digit) {
String str = String.valueOf(digit);
return = str.substring(str.length() - 2);
}
Otherwise, where you call the method, you can format it:
String.format("%02d", lastTwo(digit))
I am using the following:
int i = Integer.parseInt(args[2]);
Are there any other ways to get an integer from a string? If the number is really small as it is then doe the Byte and Char objects provide something similar?
Yes. There's:
Byte.parseByte(s); -- parses a Byte from a String
Short.parseShort(s); -- parses a Short from a String
And for larger numbers there's:
Long.parseLong(s);
-- Float is an imprecise representation of a floating point number using 32 bits
Float.parseFloat(s);
-- Double is an imprecise representation of a floating point number using 64 bits
Double.parseDouble(s);
-- BigIntegers is an integer of arbitrary size as is accurate
new BigInteger(s);
-- BigDecimal is a floating point number of arbitrary size as is accurate
new BigDecimal(s);
Yes, you can use the Short.parseShort(String) and Byte.parseByte(String) wrapper methods to parse smaller integer values.
Other ways to get an integer from a String:
String value = "2";
int i = Integer.valueOf(value);
System.out.println("i = " + i);
Scanner scanner = new Scanner(value);
i = scanner.nextInt();
System.out.println("i = " + i);
You also should wrap that in a try catch block so your code will not blow up if you try to pass it a non-integer value.
I need to compute a numeric representation of a string which is bi-direction. For example, If I have a string "US" I would like an algorithm which when applied to "US" generates a number X (int or long). When another algorithm is applied to X, I want to get "US". Each string consists of two characters.
Thanks in advance.
The following does it easily by using DataInputStream and DataOutputStream to read/write to an underlying byte array.
public static void main(String[] args) {
String original = "US";
int i = stringToInt(original);
String copy = intToString(i);
System.out.println("original: "+original);
System.out.println("i: "+i);
System.out.println("copy: "+copy);
}
static int stringToInt(String s) {
byte[] bytes = s.getBytes();
if (bytes.length > 4) {
throw new IllegalArgumentException("String too large to be" +
" stored in an int");
}
byte[] fourBytes = new byte[4];
System.arraycopy(bytes, 0, fourBytes, 0, bytes.length);
try {
return new DataInputStream(new ByteArrayInputStream(fourBytes))
.readInt();
} catch (IOException e) {
throw new RuntimeException("impossible");
}
}
static String intToString(int i) {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
try {
new DataOutputStream(byteArrayOutputStream).writeInt(i);
} catch (IOException e) {
throw new RuntimeException("impossible");
}
return new String(byteArrayOutputStream.toByteArray());
}
This is in the general sense impossible; there are only 2^64 long values, and there are more than 2^64 64-character strings consisting only of the characters X, Y and Q.
Maybe you want to have a pair of hash tables A and B and a counter; if you're given a string you check whether it's in the first hash table, if so return the value you stored there, if not then you set
A[string]=counter; B[counter]=string; counter=1+counter;
What you're describing is bidirectional encryption. Something like this may help you. Another way to do this if you specifically want a numerical value, is to store the character codes (ASCII codes) of each letter. However the resulting number is going to be huge (especially for really long strings) and you probably won't be able to store it in an 32 or 64-bit integer. Even a long won't help you here.
UPDATE
According to your edit, which says that you only need two characters, you can use the ASCII codes by using getBytes() on the String. When you need to convert it back, the first two digits will correspond to the first character, whereas the last two will correspond to the second character.
This could do, assuming your Strings have length 2, i.e. consist of two Java char values:
public int toNumber(String s) {
return s.charAt(0) + s.charAt(1) << 16;
}
public String toString(int number) {
return (char)number + "" + (char)(number >> 16);
}
There are Unicode characters (those with numbers over 216) that do not fit into a single Java char, but are represented (by UTF-16) by two consecutive surrogates. This algorithm would work for a single-Character-string consisting of these two surrogates, but not for longer strings consisting of more than one such character.
Also, there are int values which do not map back to valid Unicode (or UTF-16) strings (e.g. which produce unpaired surrogates instead of valid characters). But each normal string gets converted to an int and back to the same string.