Reading an int in java as a binary sequence using ByteBuffer - java

I'm trying to read an int (32 bits) to a bytebuffer object.
I've used the method "Bytebuffer.allocate(4)", and I wish to take every 8 bits(1 byte) of the given int, into the bytebuffer object.
How can I do this?
(I need to use it in order to convert every Byte(8 bits) to a number between 0-255)
Edit: I'm just trying to get the 32 bit of an int(it's for a school project and the assignment said specifcly "we will use int not as a number, but as a binary sequence of 32 bits" and that's what I'm trying to do but with absolutely no success.
Thanks.

Use simple shift and mask operations:
byte b1 = n & 0xFf;
byte b2 = (n >> 8) & 0xFF;
byte b3 = (n >> 16) & 0xFF;
byte b4 = (n >> 24) & 0xFF;

Related

Java left shift clarification

I am unable to figure out the reason for this behavior. I want to left shift by 8 bits the byte value OxAB. Then I want to convert that to a long.
byte oneByte = (byte) 0xAB;
long converted = (oneByte & 0xFF) << 8;
System.out.println(converted);
In this case the output is 43776. However, if I change the code to this:
byte oneByte = (byte) 0xAB;
long converted = (oneByte) << 8;
System.out.println(converted);
The output changes to -21760. I have following questions:
What is the data type of 0xFF?
Why is bitwise AND with 0xFF preventing sign extension?
long converted = onebyte; // gives you -85
and if you shift it 8 times to the left it gives you exactly -21760
because during the conversion to long the left most bit is used as a sign bit.
long converted = onebyte & 0xFF; //gives you 171
and if you shift it 8 times to the left it gives you 43776
because when using the bitwise and byte, short and char are converted to an int first and then the bitwise operation is executed.
11111111111111111111111110101011 //byte 0xAB casted to int
00000000000000000000000011111111 //0xFF is an int literal
00000000000000000000000010101011 //bitwise and operation
after the bitwise and with 0xFF the sign bit is removed

bits and bytes in java

Can we have in Java one byte whose upper 4 bits represent values like 0x40/0x80 and lower 4 bits representing values like 0,1,2,3.If yes then how do we retrieve values out of that on byte?Any help is greatly appreciated.
A simple example is probably easier than using words to describe it.
byte data = 0x74;
int high4 = (data >> 4) & 0xf;
int low4 = data & 0xf;
You can create wrapper class for byte or int with methods that fidget bits.
int first4bits = (byteContainer >> 4) & 0xF;
int last4bits = byteContainer & 0xF;
The problem is that such actions are inappropriate in Java.

Issues when converting bytes to integers (Java specific?)

I'm a bit confused regarding a conversion from bytes to integers. Consider the following code:
byte[] data = new byte[] { 0, (byte) 0xF0 };
int masked = data[0] << 8 & 0xFF | data[1] & 0xFF; //240
int notMasked = data[0] << 8 | data[1]; //-16
Because bytes in java are signed, data[1] is not 240 decimal, but rather the 2's complement, -16. However, it should still be, in binary: 0x11110000 so, why do I need to do data[1] & 0xFF ?
Is Java converting everything to Integer before passing it to the | operator? Why does &0xFF make a difference then?
Java bytes are signed (unfortunately) - so when you promote the value to an int in order to perform the bitwise |, it ends up being sign-extended as 0xFFFFFFF0. That then messes up the | with data[0]. The masking with & 0xff converts it to an integer value of 240 (just 0x000000F0) instead.
However, you've stlil got a problem. This code:
int masked = data[0] << 8 & 0xFF | data[1] & 0xFF;
should be:
int masked = ((data[0] & 0xff) << 8) | (data[1] & 0xFF);
... otherwise you're masking after the shift, which won't work. I've added brackets because I'm never sure of the predence of &, << and |...
It is similar to a known "puzzle"
byte x = -1;
x = x >>>= 1;
System.out.println(x);
produces
-1
No shift? This is because before compiling arithemtic / shift / comparison expressions javac promotes byte (as well as short and char) to int or to long (if there is any long in the expression), so it works as follows
x -> int = 0xFFFFFFFF; 0xFFFFFFF >>> 1 = 0x7FFFFFF; (byte)0x7FFFFFF -> 0xFF

Java - write the first byte of an int

Ok, so I have searched and searched and nothing worked...
I have this array of int, each int occupies only the low order byte. For instance, I have
data[0] = Ox52
data[1] = Oxe4
data[2] = Ox18
data[3] = Oxcb
I want that the standard output contains exactly those bytes (or in other words, if I write this in a file and I examine the file with a Hex editor, I should see):
52e418cb
How can I do that?
Thank you for your help
The correct way of doing this is to shift the bytes according to their desired position and then stitch them together using the OR operator. But, you should also perform a bit mask on the lower 8 bits of the byte before shifting it. This is needed because a byte is first converted to an int (before the shifting is done). This is no big deal, but when the highest bit is 1 (i.e.: the byte is negative), your integer will become negative as well, which causes all the leading bits to be set on 1.
So:
(byte) 10000000 = (int) 11111111 11111111 11111111 10000000
Using this negative int value with the OR operator will cause a wrong result. So, the working line is this one:
((data[0] & 0xFF) << 24) | ((data[1] & 0xFF) << 16) | ((data[2] & 0xFF) << 8) | (data[3] & 0xFF)
The following seems to work fine. I'm using the OutputStream.write(int) method.
int[] ints = new int[] { 0x52, 0xe4, 0x18, 0xcb };
FileOutputStream os = new FileOutputStream(new File("/tmp/x"));
for (int i : ints) {
os.write(i);
}
os.close();
Results:
> hexdump /tmp/x
0000000 52 e4 18 cb
Just shift and OR them together before writing them to the file/output:
(data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3]

convert from short to byte and viceversa in Java

I'm trying to convert a short into 2 bytes...and then from those 2 bytes try to get the same short value. For that, I've written this code:
short oldshort = 700;
byte 333= (byte) (oldshort);
byte byte2= (byte) ((oldshort >> 8) & 0xff);
short newshort = (short) ((byte2 << 8) + byte1);
System.out.println(oldshort);
System.out.println(newshort);
For the value of 700 (oldshort), newhosrt is 444. After some testing, it looksl ike \tThis code only works for some values. Like...if oldshort=50, then it will work fine..but if it is -200, or bigger values than 127 (i think) it doesn't work. I guess that there is a problem with the signed bytes, two's complement value, etc...but I can't figure out how to solve it.
Any idea?? Any native way to do this in java?? Thanks in advance!
When recombining, you need to mask the byte1 to stop it being sign extended.
E.g.
short oldshort = 700;
byte byte1= (byte) (oldshort);
byte byte2= (byte) ((oldshort >> 8) & 0xff);
short newshort = (short) ((byte2 << 8) + (byte1&0xFF);
System.out.println(oldshort);
System.out.println(newshort);
EDIT:
All operations on bytes and shorts in java are actually done as integers. So when you write
+byte1, what is really happening is that the byte is first cast to an integer (sign-extended). It will still have the same value, but now has more bits. We can then mask off the bottom 8 bits to get the original 8-bits from the short - without the sign.
E.g. short =511 = 0x01FE
// lots of 0x000's because the operations are done on 32-bit int's
byte1 = (0x000001FE & 0x000000FF) = (0x01FE & 0xFF) = 0xFE = (byte)-2
byte2 = 0x1
newShort = (byte2 << 8) + (byte1 & 0xFF)
= (0x1 << 8) + (0xFE & 0xFF)
// since the ops are performed as int's
= (0x00000001 << 8) + (0xFFFFFFFE & 0x000000FF)
// 0xFFFFFFFE = -2
= (0x00000100) + (0x000000FE)
= 0x000001FE
= 511
You could also use com.google.common.primitives.Shorts, which has methods:
public static byte[] toByteArray(short value)
public static short fromByteArray(byte[] bytes)

Categories

Resources