Get two lower bytes from int variable - java

I have some data in int variables in Java (range between 0 and 64000). How to convert to byte this integer? I need just two lower bytes from int (range is ok). How to extract this?

You can get the lowest byte from the integer by ANDing with 0xFF:
byte lowByte = (byte)(value & 0xFF);
This works because 0xFF has zero bits everywhere above the first byte.
To get the second-lowest-byte, you can repeat this trick after shifting down all the bits in the number 8 spots:
byte penultimateByte = (byte)((value >> 8) & 0xFF);

You don't have to do AND operation to get the lower byte just cast it to the byte and get the lower byte in the byte variable.
try following both will give you same result
short value = 257;
System.out.println(value);
byte low = (byte) value;
System.out.println("low: " + low);
byte high = (byte)(value >> 8);
System.out.println("high: " + high);
value = 257;
System.out.println(value);
low = (byte) (value & 0xFF);
System.out.println("low: " + low);
high = (byte) ((value >> 8) & 0xFF);
System.out.println("high: " + high);
or try it on Ideone.com

Related

Negative results from bytes

I have this line below where byte[] shaBytes with value from a SHA1. The first four is added to result to a number which is used in a while loop. I'm trying to port an objC code to java while the line below results to a negative value such as -2063597568 after several iterations.
long tVar = (shaBytes[0] << 24) + (shaBytes[1] << 16) + (shaBytes[2] << 8) + (shaBytes[3] << 3);
So basically, the while loop loops when
tVar > 0xFFFFFFFFL >> 11
In objC shaBytes is an unsigned char which is used as parameter in a CC_SHA1. In objC the code would loop up 700+ iterations while my port only 3 because tVar becomes negative.
Java doesn't have unsigned bytes. All Java integer types are signed. This means that the left shift of a negative byte will be negative:
byte b = -30;
long x = b << 24;
System.out.printf("x = %d\n", x);
// prints -503316480
On other hand if you convert byte to long everything'll turn out okay:
byte b = -30;
long x = (b & 0xffL) << 24;
System.out.printf("x = %d\n", x);
// prints 3791650816
To convert byte to "unsigned" (remember, there is no unsigned stuff in Java) long value use:
long tVar = ((shaBytes[0] & 0xffL) << 24) + ((shaBytes[1] & 0xffL) << 16) + etc
This'll work because Java long is 64-bit and can handle 24 left shift of 8-bit value without signed/unsigned problems.

How to cast from int to byte, then use a bitshift operator

Why does the following not work? I cast an int to a byte, then shift the bits over by 7. I don't see any problems there.
However, I get the error message "possible loss of precision... required: byte; found: int"
pixels is an array of bytes, c is a Color object, iter is an integer.
pixels[iter++] = ((byte) c.getRed()) << 7;
pixels[iter++] = ((byte) c.getGreen()) << 7;
pixels[iter++] = ((byte) c.getBlue()) << 7;
In Java, the shift operators return an int value, even if the quantity being shifted is a byte. You need to wrap the cast to byte around the entire expression:
pixels[iter++] = (byte) (c.getRed() << 7);
pixels[iter++] = (byte) (c.getGreen() << 7);
pixels[iter++] = (byte) (c.getBlue() << 7);

Converting int to byte in Android

Actually I need to transfer the integer value along with the bitmap via bluetooth.. Now my problem is I need to transfer the integer as single byte value..
Is tat possible to convert int as single byte value.. and retrieve it as a integer there... I tried byteValue() and the casting thing but its not usefull.. If my approach is right just help me out with this or say some other way.
(Each time when I am using casting then it's returning as 65535)
What about this?
public static byte[] intToByteArray(int a)
{
byte[] ret = new byte[4];
ret[3] = (byte) (a & 0xFF);
ret[2] = (byte) ((a >> 8) & 0xFF);
ret[1] = (byte) ((a >> 16) & 0xFF);
ret[0] = (byte) ((a >> 24) & 0xFF);
return ret;
}
and
public static int byteArrayToInt(byte[] b)
{
return (b[3] & 0xFF) + ((b[2] & 0xFF) << 8) + ((b[1] & 0xFF) << 16) + ((b[0] & 0xFF) << 24);
}
If you're completely sure, that your int variable contains a byte value [-128; 127] then it should be as simple as:
int i = 100; // your int variable
byte b = (byte) i;
A single byte (8 bits) can only contain 2^8 unsigned integers, i.e [0, 255]. For signed you loose the first bit and the range becomes [-128, 127]. If your integer fits then a simple cast should work.
for 0-255 numbers.
int i = 200; // your int variable
byte b = (byte)(i & 0xFF);

Convert short to byte[] in Java

How can I convert a short (2 bytes) to a byte array in Java, e.g.
short x = 233;
byte[] ret = new byte[2];
...
it should be something like this. But not sure.
((0xFF << 8) & x) >> 0;
EDIT:
Also you can use:
java.nio.ByteOrder.nativeOrder();
To discover to get whether the native bit order is big or small. In addition the following code is taken from java.io.Bits which does:
byte (array/offset) to boolean
byte array to char
byte array to short
byte array to int
byte array to float
byte array to long
byte array to double
And visa versa.
ret[0] = (byte)(x & 0xff);
ret[1] = (byte)((x >> 8) & 0xff);
A cleaner, albeit far less efficient solution is:
ByteBuffer buffer = ByteBuffer.allocate(2);
buffer.putShort(value);
return buffer.array();
Keep this in mind when you have to do more complex byte transformations in the future. ByteBuffers are very powerful.
An alternative that is more efficient:
// Little Endian
ret[0] = (byte) x;
ret[1] = (byte) (x >> 8);
// Big Endian
ret[0] = (byte) (x >> 8);
ret[1] = (byte) x;
Figured it out, its:
public static byte[] toBytes(short s) {
return new byte[]{(byte)(s & 0x00FF),(byte)((s & 0xFF00)>>8)};
}
Short to bytes convert method In Kotlin works for me:
fun toBytes(s: Short): ByteArray {
return byteArrayOf((s.toInt() and 0x00FF).toByte(), ((s.toInt() and 0xFF00) shr (8)).toByte())
}
Several methods have been mentioned here. But which one is the best? Here follows some proof that the following 3 approaches result in the same output for all values of a short
// loops through all the values of a Short
short i = Short.MIN_VALUE;
do
{
// method 1: A SIMPLE SHIFT
byte a1 = (byte) (i >> 8);
byte a2 = (byte) i;
// method 2: AN UNSIGNED SHIFT
byte b1 = (byte) (i >>> 8);
byte b2 = (byte) i;
// method 3: SHIFT AND MASK
byte c1 = (byte) (i >> 8 & 0xFF);
byte c2 = (byte) (i & 0xFF);
if (a1 != b1 || a1 != c1 ||
a2 != b2 || a2 != c2)
{
// this point is never reached !!
}
} while (i++ != Short.MAX_VALUE);
Conclusion: less is more ?
byte b1 = (byte) (s >> 8);
byte b2 = (byte) s;
(As other answers have mentioned, watch out for LE/BE).
It depends how you want to represent it:
big endian or little endian? That will determine which order you put the bytes in.
Do you want to use 2's complement or some other way of representing a negative number? You should use a scheme that has the same range as the short in java to have a 1-to-1 mapping.
For big endian, the transformation should be along the lines of:
ret[0] = x/256; ret[1] = x%256;
public short bytesToShort(byte[] bytes) {
return ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN).getShort();
}
public byte[] shortToBytes(short value) {
byte[] returnByteArray = new byte[2];
returnByteArray[0] = (byte) (value & 0xff);
returnByteArray[1] = (byte) ((value >>> 8) & 0xff);
return returnByteArray;
}
short to byte
short x=17000;
byte res[]=new byte[2];
res[i]= (byte)(((short)(x>>7)) & ((short)0x7f) | 0x80 );
res[i+1]= (byte)((x & ((short)0x7f)));
byte to short
short x=(short)(128*((byte)(res[i] &(byte)0x7f))+res[i+1]);

How do I split an integer into 2 byte binary?

Given
private int width = 400;
private byte [] data = new byte [2];
I want to split the integer "width" into two bytes and load data[0] with the high byte and data[1] with the low byte.
That is binary value of 400 = 1 1001 0000
so data[0] should contain 0000 0001
and data[1] should contain 1001 0000
Using simple bitwise operations:
data[0] = (byte) (width & 0xFF);
data[1] = (byte) ((width >> 8) & 0xFF);
How it works:
& 0xFF masks all but the lowest eight bits.
>> 8 discards the lowest 8 bits by moving all bits 8 places to the right.
The cast to byte is necessary because these bitwise operations work on an int and return an int, which is a bigger data type than byte. The case is safe, since all non-zero bits will fit in the byte. For more information, see Conversions and Promotions.
Edit: Taylor L correctly remarks that though >> works in this case, it may yield incorrect results if you generalize this code to four bytes (since in Java an int is 32 bits). In that case, it's better to use >>> instead of >>. For more information, see the Java tutorial on Bitwise and Bit Shift Operators.
For converting two bytes the cleanest solution is
data[0] = (byte) width;
data[1] = (byte) (width >>> 8);
For converting an integer to four bytes the code would be
data[0] = (byte) width;
data[1] = (byte) (width >>> 8);
data[2] = (byte) (width >>> 16);
data[3] = (byte) (width >>> 24);
It doesn't matter whether >> or >>> is used for shifting, any one bits created by sign extension will not end up in the resulting bytes.
See also this answer.
This should do what you want for a 4 byte int. Note, it stores the low byte at offset 0. I'll leave it as an exercise to the reader to order them as needed.
public static byte[] intToBytes(int x) {
byte[] bytes = new byte[4];
for (int i = 0; x != 0; i++, x >>>= 8) {
bytes[i] = (byte) (x & 0xFF);
}
return bytes;
}
Integer is 32 bits (=4 bytes) in java, you know?
width & 0xff will give you the first byte,
width & 0xff00 >> 8 will give you the second, etc.
To get the high byte, shift right by 8 bits then mask off the top bytes. Similarly, to get the low byte just mask off the top bytes.
data[0] = (width >> 8) & 0xff;
data[1] = width & 0xff;
int width = 400;
byte [] data = new byte [2];
data[0] = (byte) ((width & 0xFF00) >> 8);
data[1] = (byte) (width & 0xFF);
for(int b = 0; b < 2; b++) {
System.out.println("printing byte " + b);
for(int i = 7; i >= 0; i--) {
System.out.println(data[b] & 1);
data[b] = (byte) (data[b] >> 1);
}
}
I suggest you have a look at the source for HeapByteBuffer. It has the conversion code for all primitive data types. (In fact you could just use a ByteBuffer ;)

Categories

Resources