I'm just wondering why my code is giving me a NumberFormatException?
From other posts on stack overflow people seem to be having trouble with whitespace, except mine doesn't seem to have this issue at all.
package suop.space;
import java.util.BitSet;
public class ColourUtils {
public static short getAlpha(final int rgb) {
return (short) ((rgb >> 24) & 0xff);
}
public static short getRed(final int rgb) {
return (short) ((rgb & 0x00ff0000) >> 16);
}
public static short getGreen(final int rgb) {
return (short) ((rgb & 0x0000ff00) >> 8);
}
public static short getBlue(final int rgb) {
return (short) (rgb & 0x000000ff);
}
public static int getRGB(int alpha, int red, int green, int blue) {
BitSet rgbValueBitSet = new BitSet(32);
addIntToBitSet(alpha, rgbValueBitSet, 0);
addIntToBitSet(red, rgbValueBitSet, 9);
addIntToBitSet(green, rgbValueBitSet, 17);
addIntToBitSet(blue, rgbValueBitSet, 25);
System.out.println("rgbValueBitSet: " + rgbValueBitSet);
StringBuilder rgbBinaryStringBuilder = new StringBuilder();
for (int i = 0; i < rgbValueBitSet.length(); i++) {
if (rgbValueBitSet.get(i)) {
rgbBinaryStringBuilder.append(1);
} else {
rgbBinaryStringBuilder.append(0);
}
}
System.out.println(rgbBinaryStringBuilder.toString());
int rgbValue = Integer.parseInt(rgbBinaryStringBuilder.toString(), 2);
System.out.println(rgbValue);
return rgbValue;
}
private static void addIntToBitSet(int inputInt, BitSet inputBitSet, int byteToStartFrom) {
char[] inputCharArray = Integer.toBinaryString(inputInt).toCharArray();
int[] inputIntArray = new int[inputCharArray.length];
for (int i = 0; i < inputCharArray.length; i++) {
inputIntArray[i] = Character.getNumericValue(inputCharArray[i]);
}
for (int i = 0; i < inputIntArray.length; i++) {
if (inputIntArray[i] >= 1) {
inputBitSet.set(i + byteToStartFrom);
} else {
inputBitSet.clear(i + byteToStartFrom);
}
}
}
}
When trying to run the program I get this error:
rgbValueBitSet: {0, 1, 2, 3, 4, 5, 6, 7, 9, 10, 12, 13, 14, 15, 17, 18, 20, 21, 22, 23, 25, 26, 28, 29, 30, 31}
11111111011011110110111101101111
Exception in thread "main" java.lang.NumberFormatException: For input string: "11111111011011110110111101101111" under radix 2
at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:67)
at java.base/java.lang.Integer.parseInt(Integer.java:660)
at suop.space.ColourUtils.getRGB(ColourUtils.java:45)
at suop.space.EffectsUtils.divideByTwo(EffectsUtils.java:19)
at suop.space.Main.main(Main.java:38)
Process finished with exit code 1
That 11111111011011110110111101101111
is what I'm trying to parse through Integer.parseInt()
.
I'm guessing that maybe it's trying to make 11111111011011110110111101101111 itself an int, which is way larger than an integer can be. The thing is that telling it the radix I thought would make it identify it as binary, although I'm not certain.
You have a string representing a 32-bit unsigned value. An 'int' is a 32-bit signed value, i.e., absent a sign in the string value, the input cannot require more than 31 bits.
That the internal representation of a negative number has the high bit set does not mean that you can explicitly set the high bit in the string representation of that number.
You're in the same situation you'd be in by trying
parseInt("4285493103", 10);
In Java 8 onwards, there is parseUnsignedInt, which looks to me like it does what you want. I can't personally vouch for that, having never needed to use it.
Otherwise, use parseLong.
by telling it the radix I thought would make it identify it as binary,
It's being parsed as binary: which means only that it is base 2. The radix changes nothing about the representation of negative values and nor does it change the absolute range allowed.
Maybe this little test program will help you to see what is going on?
class N {
static public void main(String... a) {
System.out.println(Integer.parseUnsignedInt("11111111011011110110111101101111", 2));
}
}