I want the unsigned value of a little-endian DWORD byte array.
This is what I wrote:
private long getUnsignedInt(byte[] data) {
long result = 0;
for (int i = 0; i < data.length; i++) {
result += (data[i] & 0xFF) << 8 * (data.length - 1 - i);
}
return result;
}
Is it right?
No I am afreaid that is big endian.
public long readUInt(byte[] data) {
// If you want to tackle different lengths for little endian:
//data = Arrays.copyOf(data, 4);
return ByteBuffer.wrap(data)
.order(ByteOrder.LITTLE_ENDIAN)
.getInt() & 0xFF_FF_FF_FFL;
}
The above does a 4 byte to (signed) int conversion and then make it unsigned.
Correted for BigEndian
If by DWORD you mean 32 bits unsigned int, try this
public long readUInt(byte[] data) {
return (
((long)(data[3] & 0xFF) << 24) |
((long)(data[2] & 0xFF) << 16) |
((long)(data[1] & 0xFF) << 8) |
((long)(data[0] & 0xFF) << 0));
}
Joop Eggen's answer is correct, I think this one is faster as there is no object allocation.
Related
I am attempting to store a single byte value into a position within an int, however, I am having trouble figuring out how this would be done.
I have shifted the byte that i want to store in the int to the correct value, but I am at a loss as to how i then combine this with the value.
public static int ibyteToInt(int b, int pos, int val)
{
return ((b & 0xff) << (8 * pos)) ??;
}
The simplest solution would be to unpack the 3 other bytes from the int and then recombine the 4 bytes into an int but of course this would not be very performant.
public static int bytesToInt(byte a, byte b, byte c, byte d)
{
return ((a & 0xff) << 0) | ((b & 0xff) << 8) | ((c & 0xff) << 16) | ((d & 0xff) << 24);
}
An other simple solution is clearing out the target byte, then OR-ing in the new value:
int replaceByte(int value, byte b, int pos)
{
return (value & ~(0xFF << (pos * 8))) | ((b & 0xFF) << (pos * 8));
}
This is very similar to how to do the same thing in C#, but Java requires & 0xFF to prevent sign-extension of the byte. If the "byte" is a value between 0 and 255 and passed in as an int, that step is not required.
I am trying to convert an Integer to a byte array (array of 4 bytes) and then I will extract the last 4 bits of each byte, then I will create a short from those last 4 digits of each bytes.
I have the following code but it always prints zero.
private static short extractShort(byte[] byteArray) {
short s = 1;
ByteBuffer byteBuffer = ByteBuffer.allocate(4);
for(int i = 0; i < byteArray.length; i++) {
byte lastFourBytes = extractLast4Bits(byteArray[i]);
// Uses a bit mask to extract the bits we are interested in
byteBuffer.put(lastFourBytes);
}
return ByteBuffer.wrap(byteBuffer.array()).getShort();
}
private static byte extractLast4Bits(byte byteParam) {
return (byte) ( byteParam & 0b00001111);
}
private static byte[] intToByteArray(int i) {
return new byte[] {
(byte)((i >> 24) & 0xff),
(byte)((i >> 16) & 0xff),
(byte)((i >> 8) & 0xff),
(byte)((i >> 0) & 0xff),
};
}
}
Any help will be sincerely appreciated
Once you get the byte array, try this..
short val = 0;
for (byte b : bytes) {
val <<= 4;
val |= (b&0xf)
}
If you want to do it starting from an int, you can do it like this.
int v = 0b1110_1010_1111_1001_1010_1000_1010_0111;
short verify = (short) 0b1010_1001_1000_0111;
// initialize a short value
short val = 0;
// increment from 24 to 0 by 8's the loop will
// repeat 4 times.
for (int i = 24; i >= 0; i -= 8) {
// start by shifting the result left 4 bits
// first time thru this does nothing.
val <<= 4;
// Shift the integer right by i bits (first time is
// 24, next time is 16, etc
// then mask off the lower order 4 bits of the right
// most byte and OR it to the result(val).
// then when the loop continues, val will be
// shifted left 4 bits to allow for the next "nibble"
val |= ((v >> i) & 0xf);
}
System.out.println(val);
System.out.println(verify);
For more information on bitwise operators, check out this Wikipedia link.
I convert a short number to a 3 byte array using the following code:
static byte[] convertTo3ByteArray(short s) {
byte[] ret = new byte[3];
ret[0] = (byte) (s & 0xff);
ret[1] = (byte) ((s >> 8) & 0xff);
ret[2] = (byte) (0x00);
return ret;
}
This works very well.
I found a code on Stackoverflow to convert the array back to a number:
static int convertToInt(byte[] b) {
return ((b[0] << 0) | (b[1] << 8) | (b[2] << 16));
}
And when I convert 258 to byte array, and then use this code, it returns 258.
But for number 675, this code returns -93.
How do I have to change the convertToShort method to get 675 back?
I suppose it has something to do with bitshift and loss of data? Or signed bytes?
Try with this modified method:
static int convertToShort(byte[] b) {
return (((b[0] & 0xFF) << 0) | ((b[1] & 0xFF) << 8) | ((b[2] & 0xFF) << 16));
}
In the array some bytes are negative, you need to convert them back to "positive values" with byteVal & 0xFF before doing the bit shift
A short has 16 bits of information, so that would be two bytes. When you try to store a third byte with | (b[2] << 16), it would go off the end of the short's bits, which is a problem. I.e. you can't do what you want to.
Changing to using a char datatype will fix this issue as they are the only unsigned type in Java:
https://stackoverflow.com/a/21089624/1590490
static char[] convertTo3ByteArray(short s) {
char[] ret = new char[3];
ret[0] = (char) (s & 0xff);
ret[1] = (char) ((s >> 8) & 0xff);
ret[2] = (char) (0x00);
return ret;
}
static int convertToShort(char[] b) {
return ((b[0]) | (b[1] << 8) | (b[2] << 16)); // the original << 0 shift does nothing
}
I am trying to convert a byte to integer. All the searches I have done use byte[] which I assume is any array. I want to convert F byte (not b as show below) but it gives error to change: not applicable to the argument.
byte F;
mmInStream.read(packetBytes);
b [counter]= packetBytes[0];
F=b [counter];
counter++;
temp = byteToInt(b); //Convert byte to int
Here is a byte To Int I found on one of the sites.
private int byteToInt(byte[] b) {
int value= 0;
for(int i=0;i<b.length;i++){
int n=(b[i]<0?(int)b[i]+256:(int)b[i])<<(8*i);
value+=n;
}
return value;
}
Simply do:
byte b = ...;
int signedInt = b; // For negative bytes, resulting in negative ints
int unsignedInt = 0xFF & b; // For negative bytes, resulting in positive ints
FYI: An int is 4 bytes. So, that is the reason why the methods you found on the internet are using an array of bytes. They assume you pass an array of 4 bytes, which will be stitched together to make an int.
you can use this:
int i = 234;
byte b = (byte) i;
System.out.println(b); // -22
int i2 = b & 0xFF;
System.out.println(i2); // 234
or this one also:
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 b is unsigned
int i = b & 0xff;
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);