How would I obtain a specific subset, say bits 5-10, of an int in Java?
Looking for a method where one can pass in specific bit positions. I'm not sure how I would create a mask that changes given the input, or even if that is how one should go about doing it.
I know this is how one would get the front say 10 bits of an int: (I think)
int x = num >> 22;
Say you have a number n, and want bits from i to j (i=5, j=10).
Note, that i=0 will give you the last bit
int value = n & (((1 << (j-i)) - 1) << i );
will give you the result.
The left part is obvious: you have a value, and you will put a bitmask on it.
The value of the mask is ((1 << (j-i)) - 1) << i. It says:
Take a 1 bit (value: 0000000000000001)
Shift it left j-i times (value: 2^(10-5) = 2^5 = 32 = 0000000000100000)
Deduct 1 (value: 31 = 0000000000011111) - have you seen the lowest bits reversed?
Shift it left i times (value: 31*32=992 = 0000001111100000)
So, you have got the bitmask for bits 5 - 10 (more precisely, from 5 to 9, since 10th is not included).
To obtain value of bit 1 (bits are indexed from 0 to 31)
int val = bits & 0x002;
To obtain value of bit 16
int val = bits & (1<<16);
To obtain value of bit n
int val = bits & (1<<n);
Related
I have a Java function written by another programmer, which uses bitwise manipulation. I need a function that will undo the process (if possible). Perhaps some of you are more savvy than I with these operators. Here's what needs to be undone:
public void someFunc(int[] msg, int[] newMsg) {
int i = SOME_LENGTH_CONSTANT;
for (int j = 0; j < newMsg.length; j++) {
// msg[i] Shift left by 8 bits bitwise or with next msg[i+1]
// then bitwise not (~) and bitwise and with $FFF
newMsg[j] = (~(((msg[i] & 0x0f) << 8) | (msg[i + 1]))) & 0xfff;
i += 2;
}
}
I just wanted to try to do it, here is the results of my attempt.
In the beginning I split the expression into single operations:
int t1 = msg[i] & 0x0f;
Here is we lose all except for the last 4 bits.
int t2 = t1 << 8;
Clear low 8 bits by shifting t1.
int t3 = t2 | msg[i + 1];
Here we should understand if m[i + 1] is large than 255 (particularly m[i + 1] & 0xf00 > 0), we are not able to restore the low 4 bits of m[i] because they are irreversibly overwritten.
int t4 = ~t3;
Just a negation.
newMsg[j] = t4 & 0xfff;
Take low 12 bits.
Just did these steps in reverse order:
public static void someFuncRev(int[] msg, int[] newMsg) {
for (int i = 0; i < msg.length; ++i) {
newMsg[2 * i] = (~msg[i] >> 8) & 0xf; // take 11-8 bits
newMsg[2 * i + 1] = ~msg[i] & 0xff; // take 7-0 bits
}
}
I assumed SOME_LENGTH_CONSTANT == 0. It is easy to adjust the constant.
So, when the values inside msg are <=15, the function above recovers the initial sequence.
In case when the values are >15 and <=255, for msg[i] we can restore only 4 bits, msg[i + 1] are restored completely.
If the values are >255, we can't restore msg[i] because it was correpted by bits of msg[i + 1] (look above at the point no. 3); can restore 8 bits of msg[i + 1].
I hope this helps you.
My version, behold:
public void undoFunc(int[] newMsg, int[] original) {
int i = SOME_LENGTH_CONSTANT; // starting point
for (int j = 0; j < newMsg.length; j++) { // Iterate over newMsg
original[i] = ~((newMsg[j]&0xff00)>>8)&0x000f; // &0x000f to get rid of "mistakes" when NOT-ing
original[i+1] = (~(newMsg[j]&0x00ff)) & 0xff;
// i = initial value + 2 * j
i+=2;
}
}
What does your code do?
The input is an integer array. Every two values are used to create one value in the 'output' (newMsg) array.
First, it removes the left four bits of the first value in the input.
Then it "scrolls" that value 8 places to the left and puts zeroes in the empty spots.
It places the second value, msg[i+1], in the zeroes in the four rightmost bits.
It negates the value, all ones become zeroes and all zeroes become ones.
When 4) was done, the 4 leftmost bits (cleared in step 1)) become ones, so it undoes this with a &0x0FFF.
Example iteration:
msg[i] == 1010'1011
msg[i+1] == 0010'0100
1) 1010'1011 -> 0000'1011
2) 0000'1011 -> 0000'1011'0000'0000
3) 0000'1011'0000'0000 -> 0000'1011'0010'0100
4) 0000'1011'0010'0100 -> 1111'0100'1101'1011
5) 1111'0100'1101'1011 -> 0000'0100'1101'1011
newMsg[j] == 0000'0100'1101'1011 == 0x04DB (I think, from memory)
What my code does:
Getting the value of (what used to be) msg[i+1] is easy, it's the opposite/NOT of the rightmost 8 bits. Because negating it turns all leading zeroes into ones, I'll AND it with 0xff.
Getting the value of (what used to be) msg[i] was more difficult. First scrolled the leftmost 8 bits to the right. Then I negate the value. But the four unused/lost bits are now ones, and I expect that the OP wants these to be zeroes, so I &0x000f it.
NOTE: I used hexes with leading zeroes to make it more clear. These are not necessary.
NOTE: I divided the binary numbers into four bits for readability. So 0000'0100'1101'1011 is actually (0b)0000010011011011.
The values of msg[i+1] are recovered, but the leftmost four bits of msg[i] are lost.
Fwew.
Original Post:
In your code, you use &. What & does, is turn all 'agreeing bits' (when a bit from byte a and the equally significant bit from byte b are both 1) into 1s and the rest into 0s. This means that all bits that don't agree are, as #Mike Harris said, gone and destroyed.
Example & (and operation):
1010 & 0110 =
1 & 0 => 0
0 & 1 => 0
1 & 1 => 1
0 & 0 => 0
= 0010
As you see, only the second and third most significant bits (or zero-inclusive first and second least significant bit) of byte a are kept (bit #4/#0 is 'luck'), because they are 1s in byte b.
You can reverse all bits that are 1s in byte b in your code (one of which is fff, or 1111 1111 1111 in binary, though remember all bits more significant than the first one are removed, because 1111 1111 1111 == 000000000...00111111111111). But this won't reverse it, and only works depending on what the purpose of reversing it is.
More about the AND Bitwise operation on Wikipedia.
I have 16 bits register which contain some values in LSB and MSB:
LSB:
At bit 0...1 the value is 0
At bit 2 the values is 0
MBS:
At MSB I need to write value 20
So the value that should be written in register is 0 + 0 + 20 = 160
When I'm reading register the I'm doing it on this way:
for the 1st value in bit [0...1]:
firstVal = (valFromReg & (((1 << 2)-1) << 1) / 2)
secondVal = (valFromReg & 4) / 4
But how to read/convert the third value to get number 20?
In Java, a short is a (signed) 16-bit value. You want to split that into 3 values:
Value a is a 2-bit value in bits 0-1
Value b is a 1-bit value in bit 2
Value c is a 13-bit value in bits 3-15
Bit-wise, that can be represented like this: cccc cccc cccc cbaa
To extract the 3 values from the 16-bit reg value, you'd do this:
short reg = /*register value*/;
int a = reg & 0x0003;
int b = (reg >> 2) & 0x0001;
int c = (reg >> 3) & 0x1fff;
To go the other way, you'd do this:
short reg = (short)((c << 3) | (b << 2) | a);
This of course assumes that the values are within value range, i.e. a = 0-3, b = 0-1, and c = 0-8191.
Some things in the question are not quite clear for me...
like:
At MSB I need to write value 20
back in my times MSB was only 1 bit and was only possible to write true or false...
anyways...
A 16 bits signal fits pretty good in an integer...
so you could basically get that register and manipulate it as an integer, then representing that as a binary number AS STRING will lets you to get the MSB or even the bit at any wanted position...
Do this:
Example
int register = -128;
String foo = String.format("%16s", Integer.toBinaryString(register)).replace(' ', '0');
System.out.println(register);
System.out.println(foo);
System.out.println(foo.charAt(0)); //char at 0 is the MSB....
edit: This question is not a duplicate. The whole point is to solve the question using masks and bit shifts.
I have a terrible programming teacher that introduces concepts without explaining them or providing material to understand them, and he's to arrogant and confrontational too seek help from.
So naturally, I'm stuck on yet another question without any guidance.
Given an integer variable x, write Java code to extract and display each of the four bytes of that integer individually as 8-bit values.
I'm supposed to use masking and bit shift operations to answer this question. I understand that masking means turning bits "on or off" and I understand that an integer has 32 bits or 4 bytes. But that information doesn't help me answer the question. I'm not necessarily asking for the entire solution, but any help would be appreciated.
Using masks and shifting to extract bytes from an integer variable i,
The bytes from most significant (highest) to least are:
byte b3 = (byte)((i>>24));
byte b2 = (byte)((i>>16)&255);
byte b1 = (byte)((i>>8)&255);
byte b0 = (byte)((i)&255);
out.println("The bytes are " + b3 + ", " + b2 + ", " + b1 + ", " + b0);
You could use a ByteBuffer
int myInt = 123;
byte[] bytes = ByteBuffer.allocate(4).putInt(myInt).array();
Then you can do whatever you want with it. If you want all bits you could do something like this:
for(int i = 0; i < 4; i++)
{
for(int j = 0; j < 8; j++)
{
if(bytes[i] & (1 << j))
{
System.out.print("1");
}
else
{
System.out.print("0");
}
}
System.out.print(" ");
}
I have not tested this code because I do not have Java on this PC, but if it does not work let me know. However this sould give you a ruff idea of what has to be done.
Firstly you have to understand bitwise operators and operations. ( https://docs.oracle.com/javase/tutorial/java/nutsandbolts/op3.html )
Boolean logic states that x & 1 = x and x & 0 = 0.
Knowing this we can create a mask for, lets say the least significant 4 bits of an 8 bit number: 11001101 & 00001111 = 1101 (205 & 0x0f = 13).
(we ignore the first 4 zeros and we got our 4 bits)
What if we need the most significant bits?
we apply the same idea, but now the mask will change, according to the bits we need: 11001101 & 11110000 = 11000000 (205 & 0xf0 = 192)
whoops... we got 4 zeros.
How can you get rid of that? Shifting to the right with 4 positions.
so 11000000 >> 4 = 1100 (most significant 4 bits)
I hope this example will help you to get a better understanding of bitwise operations.
One simple solution could be
bit0 = (x & 0xff000000) >> 24;
bit1 = (x & 0x00ff0000) >> 16;
bit2 = (x & 0x0000ff00) >> 8;
bit3 = (x & 0x000000ff);
(bit0 is MSB).
Masking isn't quite turning bits "on" or "off". It is a way to extract only the bits you want from the variable you are using. Lets say that you have the binary number 10011011 and you want the value of the rightmost 4 bits. To do this, you construct another binary number of the same length where there are 0's in the places that you don't want and 1's in the places that you do. Therefore, our binary number is 00001111. You then bitwise AND them together:
1 & 0 = 0
0 & 0 = 0
0 & 0 = 0
1 & 0 = 0
1 & 1 = 1
0 & 1 = 0
1 & 1 = 1
1 & 1 = 1
In java, using hex instead of binary since java doesn't have binary literals, this looks like
int result = 0x9B & 0x0F;
//result is 0xB (or 11 in decimal)
Bit shifting is just what it sounds like. If you have 10011111 and shift it right 2 bits you get 00100111. In java a bit shift of 2 looks like
int result = 0x9B >> 2;
For your program the idea is this:
Mask the rightmost byte of your integer
Shift integer right 8 bits
Repeat three more times
I have found an code in my project for generation of PKs and I simply cannot understand what this code do.
Can anyone give me some directions or ideas or explanation?
Integer typecode = ((AbstractEntity)object).getTypeCode();//this is unique number for every type
Long counter = Long.valueOf(this.fetchNextCounter(typecode.intValue())); //this returns a counter for each type
Integer clusterid = Integer.valueOf(0);
Integer millicnt = Integer.valueOf(0);
Long creationtime = Long.valueOf((new DateTime()).getMillis());
//here is where the magic starts and I cant simply understand a thing
if(typecode.intValue() >= 0 && typecode.intValue() <= 32767) {
long longValue = counter.longValue() << 15 | (long)typecode.intValue() << 48 & -281474976710656L;
longValue += ((long)clusterid.intValue() & 15L) << 44 & 263882790666240L;
longValue += creationtime.longValue() - 788914800000L << 4 & 17592186044400L;
longValue += (long)(clusterid.intValue() >> 2) & 12L;
longValue += (long)millicnt.intValue() & 3L;
longValue &= -8796093022209L;
return Long.valueOf(longValue);
} else {
throw new RuntimeException("illegal typecode : " + typecode + ", allowed range: 0-" + 32767);
}
I would appreciate everyone who can help? The problem we have is that we have typecodes which are bigger then 32767 and as the algorithm shows this doesn't work but why and how can we change it?
Line by line (with added clarifying parentheses):
long longValue = counter.longValue() << 15 | (((long)typecode.intValue() << 48) & -281474976710656L);
It computes the binary-OR of two values:
counter shifted left by 15 bits
typecode shifted left by 48 bits and applied the mask -281474976710656 (the same as 0xFFFF000000000000). This mask seems redundant.
-
longValue += (((long)clusterid.intValue() & 15L) << 44) & 263882790666240L;
It gets the last 4 bits of of clusterid (& 15, same as & 0xF) , shifts it left by 44 bits, then applies the mask 263882790666240L, that is the same as 0xF00000000000. This last mask apply seems to be redundant. Sums it to the result.
longValue += ((creationtime.longValue() - 788914800000L) << 4) & 17592186044400L;
It subtracts the creationtime by 788914800000L (that is the timestamp for 12/31/1994 # 11:00pm (UTC)), shifts 4 bits left, then applies the mask 17592186044400L, that is the same as 0xFFFFFFFFFF0. Sums it to the result.
longValue += (long)(clusterid.intValue() >> 2) & 12L;
Then it gets the cluster id, discards the last 2 bits (>> 2) and applies the mask 12L, that is the same as getting the 3rd and 4th bits (5th and 6th in the original number). Sums it to the result.
longValue += (long)millicnt.intValue() & 3L;
It gets the last 2 bits of millicnt (& 3L). Sums it to the result.
longValue &= -8796093022209L;
Then it applies the the mask -8796093022209L to the reslt, that is the same as 0xFFFFF7FFFFFFFFFF. It in practice zeroes the 44th bit of the resulting number.
The operators <<, >>, | and & are all bitwise operators. The act on the individual bits of the underlying binary value of those numbers. For more information, give this article a read. And then take a sample value and work through the code.
This bit of code is putting parts of the bit representation of the typecode, counter, longvalue, creationtime, clusterid and millicnt after each other. This creates a new number that is unique because the combination of all the above is unique. However the way the values are packed in does mean that you can't have more then 32767 typecodes. There just isn't enough space.
You can see the process in detail by using Long.toBinaryString() to see the bit representations of the input and the longValue after each step.
Since these are primary keys for a database I reckon you can let the database generate the key for you though.
I need a specific bit in a byte value stored as int value. My code is as shown below.
private int getBitValue(int byteVal, int bitShift){
byteVal = byteVal << bitShift;
int bit = (int) (byteVal >>>7);
return bit;
}
It is working when I give the bitshift as 1 but when I give the bitshift as 2 and the byteVal as 67(01000011 in binary), I get the value of 'byteVal' as 268 while 'byteVal' should be 3(000011 in binary) after the first line in the method(the left shift). What am I doing wrong here?
For some reason when I try your code I don't get what you get. For your example, if you say byteVal = 0b01000011 and bitShift = 2, then this is what I get:
byteVal = 0b01000011 << 2 = 0b0100001100
bit = (int) (0b0100001100 >>> 7) = (int) (0b010) // redundant cast
returned value: 0b010 == 2
I believe what you intended to do was shift the bit you wanted to the leftmost position, and then shift it all the way to the right to get the bit. However, your code won't do that for a few reasons:
You need to shift left by (variable length - bitShift) to get the desired bit to the place you want. So in this case, what you really want is to shift byteVal left by 6 places, not 2.
int variables are 32 bits wide, not 8. (so you actually want to shift byteVal left by 30 places)
In addition, your question appears to be somewhat contradictory. You state you want a specific bit, yet your example implies you want the bitShift-th least significant bits.
An easier way of getting a specific bit might be to simply shift right as far as you need and then mask with 1: (also, you can't use return with void, but I'm assuming that was a typo)
private int getBitValue(int byteVal, int bitShift) {
byteVal = byteVal >> bitShift; // makes the bitShift-th bit the rightmost bit
// Assumes bit numbers are 0-based (i.e. original rightmost bit is the 0th bit)
return (int) (byteVal & 1) // AND the result with 1, which keeps only the rightmost bit
}
If you want the bitShift-th least significant bits, I believe something like this would work:
private int getNthLSBits(int byteVal, int numBits) {
return byteVal & ((1 << numBits) - 1);
// ((1 << numBits) - 1) gives you numBits ones
// i.e. if numBits = 3, (1 << numBits) - 1 == 0b111
// AND that with byteVal to get the numBits-th least significant bits
}
I'm curious why the answer should be 3 and I think we need more information on what the function should do.
Assuming you want the value of the byteVal's lowest bitShift bits, I'd do the following.
private int getBitValue(int byteVal, int bitShift){
int mask = 1 << bitShift; // mask = 1000.... (number of 0's = bitShift)
mask--; // mask = 000011111 (number of 1's = bitShift)
return (byteVal & mask);
}
At the very least, this function will return 1 for getBitValue(67, 1) and 3 for getBitValue(67,2).