I have 1 number which require 9 bits and the bits spread into 2 bytes (Most Significant Byte and Least Significant Byte).
The MSB is like:
0?????[Bit8][Bit7]
And the LSB is like:
0[Bit6][Bit5][Bit4][Bit3][Bit2][Bit1][Bit0]
My number consists on 9 bits from Bit0 to Bit8. ? indicates either 1 or 0.
So, how do I get my number?
I can think of shifting the bits in MSB left by 7 bits and then combine it with LSB to form a 16 bit number. However, how can I avoid losing Bit8 when shifting MSB left by 7 bits?
Java bitwise operators are done on 32-bit ints in this case, so you don't lose [bit8] when you shift to the left.
int msb = 0xFF;
int lsb = 0xFF;
int result = ( ( msb & 0x3 ) << 7 ) | ( lsb & 0x7F );
System.out.println(result == 0x1FF);
Additionally , you can try the BitSet class
http://docs.oracle.com/javase/7/docs/api/java/util/BitSet.html
for working on arbitrary bit lengths [ example size 9 here]
Related
I have tried to convert 248 to binary and then convert it to two's compliment and finally convert it back to decimal.
Problem: result is 8 not -8
Convert the hex number digit by digit to a 4-bit binary, for example (A) to (1010) and put then together. Now you can calculate the 2‘s complement as explained below.
You'll see you need at least 9 bits for (F8)16, so if you're only working with a 8-bit variable for instance, you might encounter issues.
Calculating the 2‘s complement:
(248)10 = (0 1111 1000)2.
Complement all the bits:
(1 0000 0111)2.
Add 1:
(1 0000 1000)2.
This will give you (-248)10. Notice that if you're only looking at the last 8 bits (0000 1000)2, the bit string evaluates to 8. I hope this helps in some way.
Java specifically keeps a single byte in the min/max range of -128 to 127.
A value like 248 (hex: 0xF8) is already stored as a Short (2 bytes or 16 bits) in Java.
[0000 0000] [1111 1000] = 248 in Java. But you need only [1111 1000] for -8.
You'd think "If I remove starting byte [0000 0000] then it works..??" No because now you have 1 byte left and that remaining byte with [1111 1000] alone cannot make 248 since Java's maximum for a single byte is 127.
Solution:
In those available 16 bits, replace all bits leading up to your value with 1.
Visually your bits [0000 0000] [1111 1000] = 248 must become as [1111 1111] [1111 1000] = -8.
One quick way to achieve the result is through this logic result = (-256) | ( x );.
Code example:
int x = 248; //# your input value from reading
int result = (-256) | ( x );
System.out.println("value is " + result ); //# gives: value is -8
This question already has answers here:
java byte data type
(3 answers)
Closed 8 years ago.
since english isn't my main language and i've didn't find any pointers as to how to manually calculate the new number.
Example:
byte b = (byte) 720;
System.out.println(b); // -48
I know that most primary data types use the two complement.
Byte value ranges from -128 to 127, so it's expected to round the number down to something that fits in byte.
The Question is how do i manually calculate the -48 of the typecasted 720? I've read that i have to convert it to two complement, so taking the binary number, searching from right to left for the first one and then inverting all others and since byte only has 8 bits, take the first 8 bits. But that didn't quite work for me, it would be helpful if you would tell me how to calculate a typecasted number that doesn't fit into byte. Thanks for reading! :)
The binary representation of 702 is
10 1101 0000
Get rid of everything except the last 8 bits (because that's what fits into a byte).
1101 0000
Because of the leading 1, get the complement
0010 1111
and add 1
0011 0000
and negate the value. Gives -48.
In Java, integral types are always 2's complement. Section 4.2 of the JLS states:
The integral types are byte, short, int, and long, whose values are 8-bit, 16-bit, 32-bit and 64-bit signed two's-complement integers
You can mask out the least significant 8 bits.
int value = 720;
value &= 0xFF;
But that leaves a number in the range 0-255. Numbers higher than 127 represent negative numbers for bytes.
if (value > Byte.MAX_VALUE)
value -= 1 << 8;
This manually yields the -48 that the (byte) cast yields.
First what happens is the value (in binary) is truncated.
720 binary is 0b1011010000
We can only fit 8 bits 0b11010000
first digit 1, so the value is negative.
2's compliment gives you -48.
This is close to redundant with the answer posted by rgettman, but since you inquired about the two's complement, here is "manually" taking the 2's complement, rather than simply subtracting 256 as in that answer.
To mask the integer down to the bits that will be considered for a byte, combine it bitwise with 11111111.
int i = 720;
int x = i & 0xFF;
Then to take the two's complement:
if (x >> 7 == 1) {
x = -1 * ((x ^ 0xFF) + 1);
}
System.out.println(x);
I used the random.nextBytes() method and it generate random bytes. But i want every byte to have a fixed length of 8 bits. How do i do that?
SecureRandom random=new SecureRandom();
byte[] data=new byte[2];
random.nextBytes(data);
System.out.println(Integer.toBinaryString(data[0]));
System.out.println(Integer.toBinaryString(data[1]));
This is the output i get
1000
110010
Thanks
The bytes in the array are already a fixed length of 8 bits. If what you really mean is that you want to print them with a fixed length of 8 bits you can do this:
System.out.println(String.format("%8s", Integer.toBinaryString(data[0] & 0xFF)).replace(' ', '0'));
System.out.println(String.format("%8s", Integer.toBinaryString(data[1] & 0xFF)).replace(' ', '0'));
will print
00001000
00110010
The other suggestions will not work properly for values > 128 (or < 0) unless you add 512 and mask properly, then is is actually nicer:
System.out.println(Integer.toBinaryString((0x100|0xff&data[1]).substring(1))
I am adding this last part, giving credit to Hot Licks since it is the best I have seen. It works with all types accepted by Integer.toBinaryString().
Integer.toBinaryString(0x300+b).substring(2) //for b < 256
If you want a 16 bit result you can do:
Integer.toBinaryString(0x30000+bb).substring(2) //for bb < 65536
Generalized for 1 to 62 bits for n < 2^62:
int bits = 8;
Long mask = (1L << bits) - 1;
Long.toBinaryString((3L << bits) + (mask & n)).substring(2);
63 bits is a special case:
Long.toBinaryString((1L << bits) + (mask & n)).substring(1);
Slightly simpler: Integer.toBinaryString(768+b).substring(2)
I guess this is a difference between binary and decimal. Normally, we think of a byte by definition as having 8 bits. Whereas, an ordinary 8 digit number must start with a non-zero digit (unless it is a business number like an ISBN), an 8-bit byte can start with a 0.
So it seems that you want the most significant bit to be 1 - I think.
Well there is a simple way to "fix" that: number | 128. And it shouldn't harm the randomness.
Consider the following Java code:
byte a = -64;
System.out.println(a << 1);
The output of this code is -128
I tried as follows to figure out why this is the output:
64 = 0 1000000 (the MSB is the sign bit)
-64= 1 1000000 (Tow's complement format)
Expected output after shifting:
1 0000000 (This is equal to 0, because the MSB is just a sign bit)
Please anyone explain what I am missing.
The two's complement representation of -128 is 10000000, thus your results are correct.
10000000 is -128
10000001 is -127
10000010 is -126
...
So 10000000 is not 0. It is -128 which was your output.
This program
System.out.println(Integer.toBinaryString(-64));
System.out.println(Integer.toBinaryString(-64 << 1));
System.out.println("-64 << 1 = " + (-64 << 1));
prints
11111111111111111111111111000000
11111111111111111111111110000000
-64 << 1 = -128
You can see that -64 << 1 is the same as -64 except all the bits have been shift left by 1 (the lowest bit becomes a 0)
In two's complement, the MSB is not just a sign bit, you're thinking ones'-complement maybe? In 8 bit two complement,
10000000 = 0x80 = -128
In shift operators sign bit is ignored. So 1 1000000 << 1 is 10000000 which is -128.what's the problem?
Our machines are using two's complement to represent numbers (signed and unsigned). For representing a negative number machine negates it's positive and adds 1.
-128 is !10000000 + 1 = 01111111 + 1 = 10000000
EDIT:
I was wrong, only right shift operator's ignoring the sign bit. 10100000 << 1 == 01000000
For unsigned right shifting there's an operator >>> which shifts sign bit too.
11000000>>1 == 10100000 and 11000000>>>1 == 01100000
<< means multiply by 2
>> means divide by 2
And, during shift operations don't consider signed bit.
I’m wondering. << 1 (ignoring all details) is “multiply with 2.” -64 * 2 = -128. So why are you wondering that it indeed is -128?
I have an int and I want to invert the bits of it using the ~ bit operator. This should be a very simply thing to do, however I tried and it doesn't work. I suppose this is because java uses two's complement to represent it's int. So what is the most efficient way to do this? 50 when inverted should be 13 and that's the value I'd like to have
It seems you want only the part of the bitwise complement until the most signifficant set bit of the input. Then you just have to mask the complement,
int invert(int n) {
return ~n & mask(n);
}
int mask(int n) {
n |= n >> 1;
n |= n >> 2;
n |= n >> 4;
n |= n >> 8;
return n | (n >> 16);
}
Java int is 32-bit long with 1 bit used for sign. Therefore 50 is represented in binary as 00000000000000000000000000110010. If you bit-invert this, you'll get 11111111111111111111111111001101, which is java integer value -51 in decimal notation.
Since an int should be at least 32 bits wide, ~50 is definitely not 13. I think you are assuming the int to be only 8 bits wide, which may have been the case some 237 years ago, but definitely not nowadays and not in Java, anyway. If you need a data type that is guaranteed to be 8 bits wide, use byte.
But even then ~50 is not 13, only if take the least significant 6 bits into account. But all this doesn't have anything to do with two's complement.