How to convert big numbers from one base to another - java

I am trying to convert a SQL function into Groovy for usage in Elasticsearch, but I am stuck at this stage. Considering, I have never touched java or groovy in my life, what am I doing wrong?
CODE
public String convertFromBaseToBase(String str, int fromBase, int toBase) {
return Integer.toString(Integer.parseInt(str, fromBase), toBase);
}
output = convertFromBaseToBase("8f8f87878f8f8080", 16, 10);
System.out.print(output);
Taken from Convert from one base to another in Java
ERROR
java.lang.NumberFormatException: For input string: "8f8f87878f8f8080"
at java_lang_Integer$parseInt.call(Unknown Source)
at Script1.convertFromBaseToBase(Script1.groovy:2)
at Script1.run(Script1.groovy:5)

8f8f87878f8f8080 is a very big number (10344635885392199808 in decimal), and will not fit inside an Integer.
You will have to use BigInteger for such big numbers.
public static String convertFromBaseToBase (String str, int fromBase, int toBase){
return (new BigInteger(str, fromBase)).toString(toBase);
}
Working Code --> https://www.onlinegdb.com/B1mMEcKPX
BigInteger -->https://docs.oracle.com/javase/7/docs/api/java/math/BigInteger.html#toString(int)

Related

error while parsing an int from a char in String

import java.util.*;
public class test
{
public static void main(String[] args)
{
int i = 123;
String s = Integer.toString(i);
int Test = Integer.parseInt(s, s.charAt(0)); // ERROR!
}
}
I want to parse the input string based on char position to get the positional integer.
Error message:
Exception in thread "main" java.lang.NumberFormatException: radix 49 greater than Character.MAX_RADIX
at java.lang.Integer.parseInt(Unknown Source)
at test.main(test.java:11)
That method you are calling parseInt(String, int) expects a radix; something that denotes the "number system" you want to work in, like
parseInt("10", 10)
(10 for decimal)! Instead, use
Integer.parseInt(i)
or
Integer.parseInt(i, 10)
assuming you want to work in the decimal system. And to explain your error message - lets have a look at what your code is actually doing. In essence, it calls:
Integer.parseInt("123", '1')
and that boils down to a call
Integer.parseInt("123", 49) // '1' --> int --> 49!
And there we go - as it nicely lines up with your error message; as 49 isn't a valid radix for parsing numbers.
But the real answer here: don't just blindly use some library method. Study its documentation, so you understand what it is doing; and what the parameters you are passing to it actually mean.
Thus, turn here and read what parseInt(String, int) is about!
Integer.parseInt(parameter) expects the parameter to be a String.
You could try Integer.parseInt(s.charAt(0) + ""). The +"" is to append the character to an empty String thereby casting the char to String and this is exactly what the method expects.
Another method to parse Characters to Integers (and in my opinion much better!) is to use Character.getNumericValue(s.charAt(0));
Check this post for further details on converting char to int
Need to convert String.valueOf(s.charAt(0)) to String.valueOf(s.charAt(0)) i.e. Char to String.
import java.util.*;
public class test
{
public static void main(String[] args)
{
int i = 123;
String s = Integer.toString(i);
int Test = Integer.parseInt(String.valueOf(s.charAt(0)));
}
}
Let use what we have here.
To parse one digit from a String into an integer. Use getNumericValue(char)
In your case, to get the first character into a number :
int n = Character.getNumericValue(s.charAt(0));
Be aware that you should take the absolute value if you integer can be negative.

Converting from Hexadecimal to Bytes

I have some Java code that converts a Hexadecimal string into bytes. It seems to work okay for very short hexadecimal strings but flags an error if I use a long string, but I cant figure out why. I'm new to Java and programming in general. Feel free to point out any other areas which I could improve.
Here is my code:
public class Hextobinary {
static String hexToBinary(String hex) {
int i = Integer.parseInt(hex, 16);
String bin = Integer.toBinaryString(i);
return bin;
}
public static void main(String[] args) {
String h = "5F";
String x = hexToBinary(h);
System.out.println(x);
}
}
Many Thanks
There is a built-in for this using DatatypeConverter, so you may not have to do it yourself.
import javax.xml.bind.DatatypeConverter;
public class HexUtils {
public String toHex(final byte[] arr) {
return DatatypeConverter.printHexBinary(arr);
}
public byte[] fromHex(final String str) {
return DatatypeConverter.parseHexBinary(str);
}
}
You are parsing your string to an int. That will work for short hex strings, but not for longer ones. An int is 32 bits, or 8 hex characters. Any string longer than that will not fit into an int.
If you do write your own method, then split the hex string up into two character chunks, and process each pair of characters separately into a byte, and store the bytes in a byte array. That will allow you to deal with longer hex strings.
If you are using huge strings, the type int (Integer) of the variable i cannot store the value contained in the string hex. An Integer can only store values ranging from -80000000 (hexadecimal) to +7FFFFFFF. Any longer string will cause your function to produce false results.
One quick solution is to use the type Long (and the function parseLong) instead of Integer. The type Long can hold values ranging from -8000000000000000 (hexadecimal) to +7FFFFFFFFFFFFFFF. But if you need to convert longer strings, this is not going to work anymore.

java convert to int

I am trying to convert to int like this, but I am getting an exception.
String strHexNumber = "0x1";
int decimalNumber = Integer.parseInt(strHexNumber, 16);
Exception in thread "main" java.lang.NumberFormatException: For input string: "0x1"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48)
at java.lang.Integer.parseInt(Integer.java:458)
It would be a great help if someone can fix it.
Thanks.
That's because the 0x prefix is not allowed. It's only a Java language thing.
String strHexNumber = "F777";
int decimalNumber = Integer.parseInt(strHexNumber, 16);
System.out.println(decimalNumber);
If you want to parse strings with leading 0x then use the .decode methods available on Integer, Long etc.
int value = Integer.decode("0x12AF");
System.out.println(value);
Sure - you need to get rid of the "0x" part if you want to use parseInt:
int parsed = Integer.parseInt("100", 16);
System.out.println(parsed); // 256
If you know your value will start with "0x" you can just use:
String prefixStripped = hexNumber.substring(2);
Otherwise, just test for it:
number = number.startsWith("0x") ? number.substring(2) : number;
Note that you should think about how negative numbers will be represented too.
EDIT: Adam's solution using decode will certainly work, but if you already know the radix then IMO it's clearer to state it explicitly than to have it inferred - particularly if it would surprise people for "035" to be treated as octal, for example. Each method is appropriate at different times, of course, so it's worth knowing about both. Pick whichever one handles your particular situation most cleanly and clearly.
Integer.parseInt can only parse strings that are formatted to look just like an int. So you can parse "0" or "12343" or "-56" but not "0x1".
You need to strip off the 0x from the front of the string before you ask the Integer class to parse it. The parseInt method expects the string passed in to be only numbers/letters of the specified radix.
try using this code here:-
import java.io.*;
import java.lang.*;
public class HexaToInteger{
public static void main(String[] args) throws IOException{
BufferedReader read =
new BufferedReader(new InputStreamReader(System.in));
System.out.println("Enter the hexadecimal value:!");
String s = read.readLine();
int i = Integer.valueOf(s, 16).intValue();
System.out.println("Integer:=" + i);
}
}
Yeah, Integer is still expecting some kind of String of numbers. that x is really going to mess things up.
Depending on the size of the hex, you may need to use a BigInteger (you can probably skip the "L" check and trim in yours ;-) ):
// Convert HEX to decimal
if (category.startsWith("0X") && category.endsWith("L")) {
category = new BigInteger(category.substring(2, category.length() - 1), 16).toString();
} else if (category.startsWith("0X")) {
category = new BigInteger(category.substring(2, category.length()), 16).toString();
}

java: Long.parseLong(s,16) and Long.toHexString(l) not inverses?

I get this but yet I don't get it:
package com.example.bugs;
public class ParseLongTest {
public static void main(String[] args) {
long l = -1;
String s = Long.toHexString(l);
System.out.println(s);
long l2 = Long.parseLong(s, 16);
}
}
This fails with the following:
ffffffffffffffff
Exception in thread "main" java.lang.NumberFormatException: For input string: "ffffffffffffffff"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48)
at java.lang.Long.parseLong(Long.java:410)
at java.lang.Long.parseLong(Long.java:468)
at com.example.bugs.ParseLongTest.main(ParseLongTest.java:8)
presumably because if you literally interpreted 0xffffffffffffffffL, it would not fit in the Long number space, which is signed.
But why does Long.toHexString() produce a string that cannot be parsed by Long.parseLong(), and how do I work around this? (I need a way of getting long values to their hex string representation, and back again)
Long.parseLong(String s, int radix) doesn't understand two's complement. For negative number it expects minus sign. As bestsss already mentioned you should use Long.toString(long l, int radix) to make hex string compatible with this parsing method.
This is a known bug, it is fixed in 1.8, see http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4215269
You can use guava's UnsignedLongs.parseUnsignedLong(String s, int radix) if Java 1.8 is not an option.

Is J2ME's Integer.parseInt() broken?

While writing a game for J2ME we ran into an issue using java.lang.Integer.parseInt()
We have several constant values defined as hex values, for example:
CHARACTER_RED = 0xFFAAA005;
During the game the value is serialized and is received through a network connection, coming in as a string representation of the hex value. In order to parse it back to an int we unsuccesfully tried the following:
// Response contains the value "ffAAA005" for "characterId"
string hexValue = response.get("characterId");
// The following throws a NumberFormatException
int value = Integer.parseInt(hexValue, 16);
Then I ran some tests and tried this:
string hexValue = Integer.toHexString(0xFFAAA005);
// The following throws a NumberFormatException
int value = Integer.parseInt(hexValue, 16);
This is the exception from the actual code:
java.lang.NumberFormatException: ffaaa005
at java.lang.Integer.parseInt(Integer.java:462)
at net.triadgames.acertijo.GameMIDlet.startMIDlet(GameMIDlet.java:109)
This I must admit, baffled me. Looking at the parseInt code the NumberFormatException seems to be thrown when the number being parsed "crosses" the "negative/positive boundary" (perhaps someone can edit in the right jargon for this?).
Is this the expected behavior for the Integer.parseInt function? In the end I had to write my own hex string parsing function, and I was quite displeased with the provided implementation.
In other words, was my expectation of having Integer.parseInt() work on the hex string representation of an integer misguided?
EDIT: In my initial posting I wrote 0xFFFAAA005 instead of 0xFFAAA005. I've since corrected that mistake.
The String you are parsing is too large to fit in an int. In Java, an int is a signed, 32-bit data type. Your string requires at least 36 bits.
Your (positive) value is still too large to fit in a signed 32-bit int.
Do realize that your input (4289372165) overflows the maximum size of an int (2147483647)?
Try parsing the value as a long and trim the leading "0x" off the string before you parse it:
public class Program {
public static void main(String[] args) {
String input = "0xFFFAAA005";
long value = Long.parseLong(input.substring(2), 16);
System.out.print(value);
}
}
I'm not a java dev, but I'd guess parseInt only works with integers. 0xFFFAAA005 has 9 hex digits, so it's a long, not an int. My guess is it's complaining because you asked it to parse a number that's bigger than it's result data type.
Your number seems to be too large to fit in an int, try using Long.parseLong() instead.
Also, the string doesn't seem to get parsed if you have 0x in your string, so try to cut that off.

Categories