Actually I am not so clear about it so I put a question here, and I am also new to bit calculation. My scenario is like this, I get some hexadecimal value from CAN (A hardware device) , for one perticular value I have to read 4th byte , in this 4th byte the value of bit 5 and 6 decides the output to be written, I mean if 5 & 6 th bit is 00= off , 01= on like this. So my question is , how can we read 4th or any particular byte and in byte particular bits from a hexadecimal. If possible please give me some guidance or examples or any tutorial sites. I googled a lot but no use . Please help me in this. and I want this to be done in java.
Assume that the value is 32 bit.
for example assume the input is 0x4FAEBCDB
I am assuming you want to extract the 4 byte which is DB.
Doing the AND operation with 0x000000FF will extract just the 4th byte.
That is
0x4FAEBCDB & 0x000000FF = 0xDB
Similarly you can extract each individual bits by ANDing this byte with the particular bit as one.
for 5th bit
0xDB & (1<<5)
for 6th bit
0xDB & (1<<6)
If you wanted to extract the first byte(4F), you would do
0x4FAEBCDB & (0xFF000000)
FF stands for (1111 1111) and the rest of the bits are 0. So doing the AND operation bitwise will return the byte at the position in which we specified 1s.
Similarly (1<<5) generates 00010000.
Thus doing And operation with this will return the bit value at the particular position.
You need to use the & operator for this.
For example, if your value is in variable int x,
(x & 0xFF000000) >> 24
will provide the 4th byte. In this, if you want to pick just the 5th and 6th bits, you can use
(x & 0x30000000) >> 28
Check out the link http://docs.oracle.com/javase/tutorial/java/nutsandbolts/op3.html for more details.
Related
This question already has answers here:
Set specific bit in byte
(5 answers)
Closed 11 months ago.
I have a byte for example:
"10000110" which is 97 in decimal.
I don't know the correct ordering, some places it is written "01100001", the point is that I'm speaking about the decimal number 97 which is stored in a single byte in our app.
We don't need bigger numbers than 100 in our app in this place of data and we would like to store an additional boolean data in the last (8th) bit in the corresponding byte, so..
I would like to write a 0 in the 8th bit after I've read that bit for the boolean information.
So this way I will have my boolean data from the 8th bit, and after that I can write the 8th bit to zero, so I can read my byte to get the decimal number. (because we only use values from 0-100 the last bit should always be zero.)
I don't know if it is clear enough, please let me know if you have any questions.
So in short, my question is:
How could I write a 0 to the last bit of a byte in Java?
97 decimal is 61 (hexadecimal) or 1100001 (binary)
If you want to use the high-order bit (10000000 binary or 80 hex) to store other information, you can do this as follows:
byte b = 97;
// Set the high-order bit to 1
byte c = b | 0x80;
// Determine if the high-order bit is set or not
boolean bitIsSet = (c & 0x80) != 0;
// clear the high-order bit (remove the high-order bit to get the value)
byte d = c & 0x7F;
I hope this is clear and answers your question.
I need to generate a 3-bytes code (like A502F1). I am given a criteria:
1st byte is (serialCodeNumber / (256*256) ) & 0xFF
2nd is (serialCodeNumber / 256) & 0xFF
3th is (serialCodeNumber) & 0xFF
serialCodeNumber is a sequence 1-0xFFF
What does that mean!?
I would generate it like this:
String codeNum = new BigInteger(256, random).toString(16).toUpperCase().substring(0, 6);
But what is the right way of doing it as the requirement says?
I'm not quite sure what is meant by the serialCodeNumber, since if it is later on divided by 65025 it has to be a considerably larger number than 0xFFF (which is 4095) for it to make any reasonable sense.
But let's take a look at the conditions, they would all make sense once you are accustomed to the bitwise AND operator. A good read is available here on how it works but the meat of the matter from that question in my opinion is this sentence by Markus Jarderot:
The result is the bits that are turned on in both numbers.
Since in your conditions you have & 0xFF and 0xFF is 255, or in binary it's 11111111 the first eight bits that are all turned on. This is a neat trick to just retrieve only the first 8 bits of any number. And as we all know 8 bits make up a byte. (Are you starting to see where this all is coming together now?)
As for the conditions before the & 0xFF, some might recognize them as bit shift operations hidden behind divisions.
(serialCodeNumber / (256*256)) is equivalent to (serialCodeNumber >> 16)
and
(serialCodeNumber / 256) is equivalent to (serialCodeNumber >> 8)
But that is not that important in this case.
So the first condition takes the serialCodeNumber divides it by 65025 (256*256) and then looks at the 8 right most bits and ignores any other, from those 8 bits it constructs a byte.
In Java you can pretty much just write the condition as it is:
byte myFirstByte = (byte) ((serialCodeNumber / (256*256)) & 0xFF);
The other conditions aren't much different:
byte mySecondByte = (byte) ((serialCodeNumber / (256)) & 0xFF);
and
byte myThirdByte = (byte) ((serialCodeNumber) & 0xFF);
Once you have all three of your bytes, I'm assuming you need to convert them to a hex String. So I'll add them into a byte array.
byte[] myArray = {myFirstByte,mySecondByte,myThirdByte};
And borrow some method on how to convert byte arrays to HEX strings from this question.
String codeNum = bytesToHex(myArray);
And the result will look something like this:
F03DD7
EDIT:
Since you have to generate a serial number that has to be up to 6 bytes in value, I'd recommend using a long number.
A 6 byte number will be anywhere from 1 to 281474976710655, so you probably need to generate one randomly.
First instantiate a Random object which you will be able to poll numbers from:
Random random = new Random();
Once you have that, poll a long from it for the range 1 to 281474976710655.
For this you can borrow KennyTM's answer from this question.
So you can then generate the number like so:
long serialCodeNumber = nextLong(random, 281474976710655L)+1L;
We add the +1L at the end since we want it to include the last number as well as start from 1 instead of 0.
If you ever need to show a HEX string of the serialCodeNumber you can then just call:
String serialHex = Long.toHexString(serialCodeNumber);
But make sure to add any additional "0"s at the left side based on the length of the string so that it is 6-bytes = 12 characters long.
[EDIT]
I realized that unfortunately I oversimplified the question and the answers aren't really helping me, so I'm rephraseing it...
So, my situation I have a stream of incoming bytes (sample) in which the ONLY bit that is potentially set is the first one (0000 | 0001).
So, let's say I get a sequence of these that looks like this:
0000,000**0**,
0000,000**1**,
0000,000**0**,
0000,000**1**,
0000,000**0**,
0000,000**0**,
0000,000**0**,
0000,000**0**
I'm setting the relevant bit to bold to make it clearer as to what I'm actually collecting.
So, as these 'bits' arrive I need to sort them into something that looks like this:
0000,1010
I'm doing this by shifting the existing value >> 1 and then adding the incoming value shifted over by << 7
byte aggregateByte = 0;
//loop 8 times as incoming samples arrive...
aggregateByte = (aggregateByte >> 1) + incomingSample << 7
This (*should) produce the correct result.
HOWEVER because java doesn't have the notion of an signed/insigned, EVERY time I shift, because I'm starting on the left hand side, if the previous incoming bit was 1, java PRESERVES the 1 since it sees this as the sign bit and never allows it to reset back to 0.
So... what I need to do prior to adding my incoming bit is to flip the first bit in the existing byte to 0 and then the incoming bit will be set to whatever it needs to be set to.
Currently I'm doing this by setting a mask of 0x7F and &ing that against the byte.
So, my actual addition looks like this:
((aggregateByte >> 1) & 0x7F ) + incomingSample << 7
0x7F creates a mask that looks like this:
0111,111
So, when I & this against the existing value, it flips the last bit to 0.
I guess my question is "am I reinventing the wheel, and is there a better way to handle this, or will this reliably work and is a relatively efficient way to handle this process?"
Neither | nor & is for toggling bits. For that, you need to use ^. But 0x40 is indeed the correct value for flipping bit 6 ("7th" in your terms).
To flip bit 3:
final int N = 3;
b = (byte) (b ^ (1 << N));
I have a 3 byte signed number that I need to determine the value of in Java. I believe it is signed with one's complement but I'm not 100% sure (I haven't studied this stuff in more than 10 years and the documentation of my problem isn't super clear). I think the problem I'm having is Java does everything in two's complement. I have a specific example to show:
The original 3-byte number: 0xEE1B17
Parsed as an integer (Integer.parseInt(s, 16)) this becomes: 15604503
If I do a simple bit flip (~) of this I get (I think) a two's complement representation: -15604504
But the value I should be getting is: -1172713
What I think is happening is I'm getting the two's complement of the entire int and not just the 3 bytes of the int, but I don't know how to fix this.
What I have been able to do is convert the integer to a binary string (Integer.toBinaryString()) and then manually "flip" all of the 0s to 1s and vice-versa. When then parsing this integer (Integer.parseInt(s, 16)) I get 1172712 which is very close. In all of the other examples I need to always add 1 to the result to get the answer.
Can anyone diagnose what type of signed number encoding is being used here and if there is a solution other than manually flipping every character of a string? I feel like there must be a much more elegant way to do this.
EDIT: All of the responders have helped in different ways, but my general question was how to flip a 3-byte number and #louis-wasserman answered this and answered first so I'm marking him as the solution. Thanks to everyone for the help!
If you want to flip the low three bytes of a Java int, then you just do ^ 0x00FFFFFF.
0xFFEE1B17 is -1172713
You must only add the leading byte. FF if the highest bit of the 3-byte value is set and 00 otherwise.
A method which converts your 3-byte value to a proper intcould look like this:
if(byte3val>7FFFFF)
return byte3val| 0xFF000000;
else
return byte3val;
Negative signed numbers are defined so that a + (-a) = 0. So it means that all bits are flipped and then 1 added. See Two's complement. You can check that the condition is satisfied by this process by thinking what happens when you add a + ~a + 1.
You can recognize that a number is negative by its most significant bit. So if you need to convert a signed 3-byte number into a 4-byte number, you can do it by checking the bit and if it's set, set also the bits of the fourth byte:
if ((a & 0x800000) != 0)
a = a | 0xff000000;
You can do it also in a single expression, which will most likely perform better, because there is no branching in the computation (branching doesn't play well with pipelining in current CPUs):
a = (0xfffffe << a) >> a;
Here << and >> perform byte shifts. First we shift the number 8 bits to the right (so now it occupies the 3 "upper" bytes instead of the 3 "lower" ones), and then shift it back. The trick is that >> is so-called Arithmetic shift also known as signed shift. copies the most significant bit to all bits that are made vacant by the operation. This is exactly to keep the sign of the number. Indeed:
(0x1ffffe << 8) >> 8 -> 2097150
(0xfffffe << 8) >> 8 -> -2
Just note that java also has a unsigned right shift operator >>>. For more information, see Java Tutorial: Bitwise and Bit Shift Operators.
int id = ((reply[0] & 0x3));
id = (id<<7) | (reply[1] & 0x7F);
Suppose I have a reply array storing 2 byte reply[0] and reply[1].
I wanna read the last two bits in the first byte and all the bits in the second byte, then adding them together
why the code above is going to work, can anyone explain?
This code is not doing what you described: instead of taking the second byte in its entirety, it cuts out its last seven bits (the & 0x7F part; 0x7F is binary 01111111), and concatenates them to the two last two bits of the first number (the << 7 part).
Convert to binary and you will get your answer.
binary of 3 is 11. if you use logical & with 11 you will end up only with the last two bits. That's the answer to your first part.
For the second part, I don't think it will do what you intended it too. You can use logical AND (for carry) and logical XOR to add individual bits.
Try to figure it out ^_^