import java.util.*;
public class HelloWorld {
public static void main(String[] args) {
String s = "110101001011101110001111100110001010100001101011101010000011011011001011101111001100000011011110011";
long sum = Long.parseLong(s, 2);
System.out.println(sum);
}
}
Why do I get a NumberFormatException?
Long dimension is 64 bit, so max binary string can't be more than 64 length (you have 100). You can split your data on several 64-bit parts and collect list of Long values.
Or you can use BigInteger:
BigInteger val = new BigInteger("110101001011101110001111100110001010100001101011101010000011011011001011101111001100000011011110011", 2);
System.out.println(val.toString()); // prints '526700554598729746900966573811'
Just take a look at attached page and see what is the max and min value for specific types. Try with BigInteger as someone suggested.
Java basic data types
You are getting a NumberFormatException because the number 110101001011101110001111100110001010100001101011101010000011011011001011101111001100000011011110011 is far too large to be stored within a long in Java.
For reference, the max value for a long in Java is 9223372036854775807 in decimal. In binary, this is 111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111, which is less than:
1101 0100 1011 1011 1000 1111 1001 1000 1010 1000 0110 1011 1010 1000 0011 0110 1100 1011 1011 1100 1100 0000 1101 1110 011.
Your String is too long ;-)
Check out Long.MAX_VALUE
Related
I have a byte array of size 4096. I fill field 0 with 0xA2 and field 1 with 0xF0.
My goal is to shift field 0 by 8 bits to the left, then do an OR-operation with field 1 and store it into a short variable.
The result on paper should be:
1010 0010 (0xA2)
>>shift left by 8 bits
1010 0010 0000 (0xA20)
>>OR-operation with field 1
1010 0010 0000 (0xA20)(field 0)
1111 0000 (0xF0)(field 1)
----------------------
1010 1111 0010 (0xAF2)
There was already a similar post but it only helped a little.
Even though I'm casting it seems to cut off the shifted bits.
Here's the code.
public static void main(String[] args) {
byte[] myMem = new byte[4096];
myMem[0] = (byte)0xA2;
myMem[1] = (byte)0xF0;
short test = (short)(myMem[0] << 8 | myMem[1]);
}
Debugger shows following values:
myMem[0] = -94 (which is correctly 0xA2)
myMem[1] = -16 (which is correctly 0xF0)
test = -16 (which is wrong, 0x00A2. Should be -23824 or 0xA2F0).
Somewhere I made a logical mistake I suppose, I can't find it though.
use
short test = (short)((myMem[0] << 8) | ((myMem[1])& 0xff));
I'm new to Java and I am really confused about signed byte in Java.
byte a = -128;
byte b = 126;
System.out.println((byte)(a ^ b));
The output is -2. Can someone please explain why we get this? Is -2 the correct result for -128 XOR 126?
Another question is I have a byte b and I want it to XOR all possible bytes, my code is
byte i = -128
while (i <= 127) {
byte c = (byte) b ^ i;
i++;
}
Is it correct?
This about the representation of signed numbers in computers. They are represented as 2s-complement. This means:
126 = 0111 1110
-128 = 1000 0000
-2 = 1111 1110
Negative values in 2s-complement are formed by taking the absolute value as binary number, inverting all bits except the MSB, adding one to the result and setting the MSB which is used as sign-bit to 1, eg.:
-3:
0000 0011 absolute value (3)
0111 1100 invert all bits except MSB
0111 1101 add 1
1111 1101 set MSB to 1
binary math is pretty straight forward...
-128 in 8 bits is 10000000 (dont forget is 2 complement)
126 in 8 bits is 01111110
xor those then you get 1111 1110: which is -2 in 8 bits 2 complement
This one works fine:
short x = (short)(0xffff >>> 10);
i.e. x = 3F (63)
But when the same is done but with decimal representation:
short x = (short)((short)(-1) >>> 10);
then x is still FFFF (-1).
Why does it happen?
Because the short -1 gets promoted to a int with value -1, which is :
1111 1111 1111 1111 1111 1111 1111 1111
After shifting it 10 bits to the right, you have:
0000 0000 0011 1111 1111 1111 1111 1111
To fix it, you have to take the appropriate part of the int:
short x = (short)((-1 & 0xFFFF) >>> 10);
This way, the (-1 & 0xFFFF) is already an int, so it doesn't contain the leading 1's.
Taking the binary of 0x80000000 we get
1000 0000 0000 0000 0000 0000 0000 0000
How does this equate to -2147483648. I got this question with this program.
class a
{
public static void main(String[] args)
{
int a = 0x80000000;
System.out.printf("%x %d\n",a,a);
}
}
meow#VikkyHacks:~/Arena/java$ java a
80000000 -2147483648
EDIT I learned that 2's complement is used to represent negative numbers. When I try to equate this with that 1's complement would be
1's Comp. :: 0111 1111 1111 1111 1111 1111 1111 1111
2's Comp. :: 1000 0000 0000 0000 0000 0000 0000 0000
which again does not make any sense, How does 0x80000000 equate to -2147483648
This is what happens with signed integer overflow, basically.
It's simpler to take byte as an example. A byte value is always in the range -128 to 127 (inclusive). So if you have a value of 127 (which is 0x7f) if you add 1, you get -128. That's also what you get if you cast 128 (0x80) to byte:
int x = 0x80; // 128
byte y = (byte) x; // -128
Overflow (in 2s complement integer representations) always goes from the highest expressible number to the lowest one.
For unsigned types, the highest value overflows to 0 (which is again the lowest expressible number). This is harder to show in Java as the only unsigned type is char:
char x = (char) 0xffff;
x++;
System.out.println((int) x); // 0
This is the case when there is overflow, with respect to the range of a data type.
Here is an example that I can share.
int number = 0x80; // 0x80 is hexadecimal for 128 (decimal)
byte castedNumber = (byte)(number); // On casting, there is overflow,as byte ranges from -128 to 127 (inclusive).
System.out.println(castedNumber); //Output is -128.
Integer range for java is -2,147,483,648 to 2,147,483,647
The given is hex val 0x80000000 its equivalent decimal value is 2,147,483,648(1's complement conversion).
You can see the decimal value is not fit within the range which is called Integer overflow. Whenever overflow happens it circles itself to the other end in this case -2,147,483,648.
So I understand how to change an individual bit within a byte, what I am not sure is why my particular code is not working.
public static void setBit(byte[] input, int position, int value) {
int byteLocation = position / 8;
int bitLocation = position % 8;
byte tempByte = input[byteLocation];
if (value == 0)
tempByte = (byte) (tempByte & ~(1 << bitLocation));
else
tempByte = (byte) (tempByte | (1 << bitLocation));
input[byteLocation] = tempByte;
}
Now I have been testing it with the string "Testing1" which is 64bits long, then attempting to set the bits and display the value. It works a treat up to 46 bits, then on the 47th bit if I attempt to set it to 1 it borks up, works fine with 0 however.
Can't see the error in my ways, here's how I am testing it
String test = "Testing1";
byte[] bytes = test.getBytes();
for (int i = 0; i < bytes.length; i++)
System.out.print(String.format("%8s", Integer.toBinaryString(bytes[i])).replace(' ', '0') + "[" + i + "] ");
setBit(bytes, 44, 1);
System.out.println();
for (int i = 0; i < bytes.length; i++)
System.out.print(String.format("%8s", Integer.toBinaryString(bytes[i])).replace(' ', '0') + "[" + i + "] ");
The following is the output when I attempt to change the 47th bit to a 1
01010100[0] 01100101[1] 01110011[2] 01110100[3] 01101001[4] 01101110[5] 01100111[6] 00110001[7]
01010100[0] 01100101[1] 01110011[2] 01110100[3] 01101001[4] 11111111111111111111111111101110[5] 01100111[6] 00110001[7]
Change formatting as
Integer.toBinaryString(0xFF & bytes[i])
byte needs to be masked off because it is sign-extended, not zero-extended, to 32-bit int
The problem is you are setting the sign bit in the byte in question. So, that byte now has a negative value. You call Integer.toBinaryString(), which takes an int as it's argument, not a byte. The byte get promoted to an int, and it correctly evaluates the value of:
11101110
to it's equivalent integer:
11111111111111111111111111101110
I made your method smaller using ^ (xor)
public static void setBit(byte[] input, int position, int value) {
int byteLocation = position / 8;
int bitLocation = position % 8;
input[byteLocation] = (byte) (input[byteLocation] ^ (byte) (1 << bitLocation));
}
I haven't looked at it in too much detail but I think the problem with the one bite is that it's being extended to an int (Since it's signed, the 1 extends to a negative int).
Just take the last 8 characters of the string and it will work fine.
Ive recently had to do something like this.
I managed to achieve it through (a lot of use of the whiteboard but..) shifting the original bits right by the position of the LSB I wanted to replace and making all bits inclusive of the MSB I wanted to replace, 1's.
I then AND'ed the bits I want in place of the bits I want to replace, shifted left the same number I shifted right, OR'ing the result with the original and AND'ed by an XOR'ed mask of the replacement. (Take a breath, I'll try to explain)
Let's say I have the bytes:
1111 1010 0001 1001
and I want to replace the nibble 1010 with 0001 to produce:
1111 0001 0001 1001.
The operation I went through to achieve this is:
1) Shift right by 8 to produce:
0000 0000 1111 1010
2) OR a mask of 0xf (1111) to produce:
0000 0000 1111 1111
3) AND the replacement of 0001 with 0000 0000 1111 1111 to produce:
0000 0000 0000 0001
4) Shift left by 8 to produce:
0000 0001 0000 0000
5) Shift the mask by the LSB position and XOR with full bytes
1111 1111 1111 1111
0000 1111 0000 0000
==================
1111 0000 1111 1111
6) AND the XOR'ed, shifted mask with the original to produce:
1111 0000 0001 1001
1111 0000 1111 1111
==================
1111 0000 0001 1001
7) OR that result of the above with the replacement:
1111 0000 0001 1001
0000 0001 0000 0000
==================
1111 0001 0001 1001 << end result
==================
In java, this results in the function:
public long overwriteBits(long overwrite, long with, long shift, long mask)
{
return ((((overwrite >> shift) | mask) & with) << shift) | (overwrite & (~0 ^ (mask << shift)));
}
Where "overwrite" is the original data, "with" are the bits you want in place of the bits in position "shift" and mask is a a series of positive bits with the same length of the replacement.
To do the above I'd call (in sudo):
overwriteBits(1111101000011001, 0001, 8, 1111)
I want to mention that the above will work for replacing bits in any primitive, no need for byte arrays. e.g. Replacing 11 bits, as below:
1101001010101101 1111 0101 101 001101
with 1010 1010 101
overwriteBits(1101001010101101 1111 0101 101 001101, 1010 1010 101, 6, 11111111111)
1101001010101101 1111 0101 101 001101
1101001010101101 1010 1010 101 001101
overwriteBits(1789785421l, 1365l, 6, 0x7FF)