Wrapping 4 integers in a 64 bit long - java bitwise - java

Alright, so I have 4 integers I want to wrap in a long.
The 4 integers all contains 3 values, positioned in the first 2 bytes:
+--------+--------+
|xxpppppp|hdcsrrrr|
+--------+--------+
{pppppp} represents one value, {hdcs} represents the second and {rrrr} the last.
I want to pack 4 of these integers, in a long. I've tried the following:
ordinal = (c1.ordinal() << (14*3) | c2.ordinal() << (14*2) | c3.ordinal() << 14 | c4.ordinal());
where c1.ordinal()...c4.ordinal() is the integers to wrap.
This does not seem to work if I run a test. Lets say I want to look up the values of the last integer in the long, c4.ordinal(), where {pppppp} = 41, {hdcs} = 8 and {rrrr} = 14, I get the following results:
System.out.println(c4.ordinal() & 0xf); //Prints 14
System.out.println(hand.ordinal() & 0xf); // Prints 14 - correct
System.out.println(c4.ordinal() >> 4 & 0xf); // Prints 8
System.out.println(hand.ordinal() >> 4 & 0xf); // Prints 8 - correct
System.out.println(c4.ordinal() >> 8 & 0x3f); // Prints 41
System.out.println(hand.ordinal() >> 8 & 0x3f); // Prints 61 - NOT correct!
Now, the following is weird to me. If I remove the first two integers, and only wrap the last two, like this:
ordinal = (c3.ordinal() << 14 | c4.ordinal());
And run the same test, I get the correct result:
System.out.println(c4.ordinal() >> 8 & 0x3f); // Prints 41
System.out.println(hand.ordinal() >> 8 & 0x3f); // Prints 41 - correct!
I have no idea whats wrong. And it does not make any sense to me, that I get the correct answer if I remove the first two integers. I'm starting to thing this might have to do with the long datatype, but I've not found anything yet, that supports this theory.

Even though you are assigning the result to a long, all of the operations are performed with int values, and so the high-order bits are lost. Force "promotion" to a long by explicitly widening the values to a long.
long ordinal = (long) c1.ordinal() << (14*3) |
(long) c2.ordinal() << (14*2) |
(long) c3.ordinal() << 14 |
(long) c4.ordinal();
Also, unless you are positive that the top two bits of each value are zero, you could run into other problems. You may wish to mask these off for safety's sake:
long ordinal = (c1.ordinal() & 0x3FFFL) << (14*3) |
(c2.ordinal() & 0x3FFFL) << (14*2) |
(c3.ordinal() & 0x3FFFL) << 14 |
(c4.ordinal() & 0x3FFFL);

Related

Getting value from MSB of 16 bit register

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....

What is the purpose of left shifting zero by any amount?

Upon reading the ASM 4.1 source code I've found instances of the following:
int ASM4 = 4 << 16 | 0 << 8 | 0;
int ASM5 = 5 << 16 | 0 << 8 | 0;
Does these left shifts of zero by 8 do anything to the expression, or the 'or' by 0 for that matter?
Wouldn't it be equivalent to just have:
int ASM4 = 4 << 16;
int ASM5 = 5 << 16;
Indeed they are equivalent but one possible explanation is that they wanted to map the version numbers including both the major and minor numbers to a unique ID in their code. So in the following:
int ASM4 = 4 << 16 | 0 << 8 | 0; // this looks like 4.0.0
int ASM5 = 5 << 16 | 0 << 8 | 0; // this looks list 5.0.0
The 4 and 5 represent versions 4 and 5 respectively, and the zero in 0 << 8 could potentially be the minor numbers, and the last zero is another minor number, as in 4.0.0 and 5.0.0. But that's my guess anyway. You'd really have to ask the authors.
In context:
// ASM API versions
int ASM4 = 4 << 16 | 0 << 8 | 0;
int ASM5 = 5 << 16 | 0 << 8 | 0;
Yes, this is equivalent to
int ASM4 = 4 << 16;
int ASM5 = 5 << 16;
This is just written that way to make it clear that we are setting the 3rd byte to 4, and both lower bytes to 0. Alternatively, that it is a version number that should be read as 4.0.0.
It indeed serves no purpose, but then it is neatly and visually aligned so that the ASM developers know about the opcodes versions (if I'm not mistaken, this is the OpCodes interface you're looking at here).
The same way that you'd use 1 << 0 vs 1 << 1, etc.

Unique ID generation Algorithm

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.

Set bit values in Byte

I need to set the bit for some of the Bluetooth Features listed below using Java:
HeaderValue:BluetoothFeatures,
Tag ID:0x10,
Length:4 bytes,
Possible Values :
Bit 0 = a,
Bit 1 = b,
Bit 2 = c,
Bit 3 = d,
Bit 4 = e ....so on till bit 31.
To set the seventh bit to 1:
b = (byte) (b | (1 << 6));
To set the sixth bit to zero:
b = (byte) (b & ~(1 << 5));
(The bit positions are effectively 0-based, so that's why the "seventh bit" maps to 1 << 6 instead of 1 << 7.)
Source : Change bits value in Byte

new to java - trying to understand: checker |= (1 << val)

the following code will check to see if you have any duplicate characters in the string, but i don't understand the if clause:
public static boolean isUniqueChars(String str) {
int checker = 0;
for (int i = 0; i < str.length(); ++i) {
int val = str.charAt(i) - 'a';
if ((checker & (1 << val)) > 0)
return false;
checker |= (1 << val);
}
return true;
}
I tried to look up some references, I am new to bit shifting, all i understand is that << shifts the binary number left or right. Can you explain to me how checker |= (1 << val) works ? and that 'if' statement as well.
I was also going through this book Cracking the Code Interview and ended up googling for a clear explanations. Finally I understood the concept.
Here is the approach.
Note :
We will assume, in the below code, that the string is only lower case ā€˜aā€™ through ā€˜zā€™. This will allow us to use just a single int.
Java integer is of size 32
Number of lower case alphabets is 26
So we can clearly set 0/1 (true or false) value inside one integer in
decimal notation.
It is similar to bool visited[32] .
bool uses 1 byte. Hence you need 32 bytes for storing bool visited[32].
Bit masking is a space optimization to this.
Lets start :
You are looping through all the characters in the string.
Suppose on i'th iteration you found character 'b' .
You calculate its 0 based index.
int val = str.charAt(i) - 'a';
For 'b' it is 1. ie 98-97 .
Now using left shift operator, we find the value of 2^1 => 2.
(1 << val) // 1<<1 => 10(binary)
Now let us see how bitwise & works
0 & 0 -> 0
0 & 1 -> 0
1 & 0 -> 0
1 & 1 -> 1
So by the below code :
(checker & (1 << val))
We check if the checker[val] == 0 .
Suppose we had already encountered 'b'.
check = 0000 0000 0000 0000 0000 1000 1000 0010 &
'b' = 0000 0000 0000 0000 0000 0000 0000 0010
----------------------------------------------
result= 0000 0000 0000 0000 0000 0000 0000 0010
ie decimal value = 2 which is >0
So you finally we understood this part.
if ((checker & (1 << val)) > 0)
return false;
Now if 'b' was not encountered, then we set the second bit of checker using bitwise OR.
( This part is called as bit masking. )
OR's Truth table
0 | 0 -> 0
0 | 1 -> 1
1 | 0 -> 1
1 | 1 -> 1
So
check = 0000 0000 0000 0000 0000 1000 1000 0000 |
'b' = 0000 0000 0000 0000 0000 0000 0000 0010
----------------------------------------------
result= 0000 0000 0000 0000 0000 1000 1000 0010
So that simplifies this part:
checker |= (1 << val); // checker = checker | (1 << val);
I hope this helped someone !
Seems like I am late to the party, but let me take a stab at the explanation.
First of all the AND i.e & operation:
0 & 0 = 0
1 & 0 = 0
0 & 1 = 0
1 & 1 = 1
So basically, if you are given a bit, and you want to find out if its 1 or 0, you just & it with a 1. If the result is 1 then you had a 1, else you had 0. We will use this property of the & below.
The OR i.e | operation
0 | 0 = 0
1 | 0 = 1
0 | 1 = 1
1 | 1 = 1
So basically, if you are given a bit, and you want to do something to it so that the output is always 1, then you do an | 1 with it.
Now, In Java the type int is 4 bytes i.e. 32 bits. Thus we can use an int itself as a data-structure to store 32 states or booleans in simpler terms, since a bit can either be 0 or 1 i.e false or true. Since we assume that our string is composed of only lower case characters, we have enough space inside our int to store a boolean for each of the 26 chars!
So first we initialize our data-structure that we call checker to 0 which is nothing but 32 zeros: 0000000000000000000000.
So far so good?
Now we go through our string, for each character, first we get an integer representation of the character.
int val = str.charAt(i) - 'a';
We subtract a from it because we want our integer to be 0 based. So if vals:
a = 0 i.e. `0000000000000000000000`
b = 1 i.e. `0000000000000000000001`
c = 2 i.e. `0000000000000000000010`
d = 4 i.e. `0000000000000000000100`
Now as seen above, a is 32 zeros, but rest of the characters have a single 1 and 31 zeros. So when we use these characters, we left shift each of them by 1, i.e. (1 << val), so each of them have a single 1 bit, and 31 zero bits:
a = 1 i.e. `0000000000000000000001`
b = 2 i.e. `0000000000000000000010`
c = 4 i.e. `0000000000000000000100`
d = 8 i.e. `0000000000000000001000`
We are done with the setup. Now we do 2 things:
First assume all characters are different. For every char we encounter, we want our datastructure i.e. checker to have 1 for that char. So we use our OR property descrived above to generate a 1 in our datastructure, and hence we do:
checker = checker | (1 << val);
Thus checker stores 1 for every character we encounter.
Now we come to the part where characters can repeate. So before we do step 1, we want to make sure that the checker already does not have a 1 at the position corresponding to the current character. So we check the value of
checker & (1 << val)
So with help of the AND property described above, if we get a 1 from this operation, then checker already had a 1 at that position, which means we must have encountered this character before. So we immediately return false.
That's it. If all our & checks return 0, we finally return true, meaning there were no character repititions.
1 << val is the same as 2 to the degree of val. So it's a number which has
just one one in its binary representation (the one is at position val+1, if you count from
the right side of the number to the left one).
a |= b means basically this: set in a all binary flags/ones from the
binary representation of b (and keep those in a which were already set).
The other answers explain the coding operator usages but i don't think they touch the logic behind this code.
Basically the code 1 << val is shifting 1 in a binary number to a unique place for each character for example
a-0001
b-0010
c-0100
d-1000
As you can notice for different characters the place of 1 is different
checker = checker | (1 << val)
checker here is Oring (basically storing 1 at the same place as it was in 1<<val)
So checker knows what characters have already ocurred
Let's say after the occurence of a,b,c,d checker would look like this
0000 1111
finally
if ((checker & (1 << val)) > 0)
checks if that character has already been occured before if yes return false.To explain you should know a little about AND(&) operation.
1&1->1
0&0->0
1&0->0
So checker currently have 1 in places whose corresponding characters have already occured the only way the expression inside if statement is true
if a character occurs twice which leads 1&1->1 > 0
This sets the 'val'th bit from the right to 1.
1 << val is a 1 shifted left val times. The rest of the value is 0.
The line is equivalent to checker = checker | (1 << val). Or-ing with a 0 bit does nothing, since x | 0 == x. But or-ing with 1 always results in 1. So this turns (only) that bit on.
The if statement is similar, in that it is checking to see if the bit is already on. The mask value 1 << val is all 0s except for a single 1. And-ing with 0 always produces 0, so most bits in the result are 0. x & 1 == x, so this will be non-zero only if that bit at val is not 0.
checker |= (1 << val) is the same as checker = checker | (1 << val).
<< is left bit shift as you said. 1 << val means it's a 1 shifted val digits left.
Example: 1 << 4 is 1000. A left bit shift is the same as multiply by 2. 4 left bit shifts are 4 times 1 multiplied by 2.
1 * 2 = 2 (1)
2 * 2 = 4 (2)
4 * 2 = 8 (3)
8 * 2 = 16 = (4)
| operator is bitwise or. It's like normal or for one bit. If we have more than one bit you do the or operation for every bit.
Example:
110 | 011 = 111
You can use that for setting flags (make a bit 1).
The if condition is similar to that, but has the & operator, which is bitwise and. It is mainly used to mask a binary number.
Example:
110 | 100 = 100
So your code just checks if the bit at place val is 1, then return false, otherwise set the bit at place val to 1.
It means do a binary OR on the values checker and (1 << val) (which is 1, left shifted val times) and save the newly created value in checker.
Left Shift (<<)
Shift all the binary digits left one space. Effectively raise the number to 2 to the power of val or multiply the number by 2 val times.
Bitwise OR (|)
In each binary character of both left and right values, if there is a 1 in the place of either of the two numbers then keep it.
Augmented Assignment (|=)
Do the operation (in this case bitwise OR) and assign the value to the left hand variable. This works with many operators such as:-
a += b, add a to b and save the new value in a.
a *= b, multiply a by b and save the new value in a.
Bitwise shift works as follows:
Example: a=15 (bit representation : 0000 1111)
For operation: a<<2
It will rotate bit representation by 2 positions in left direction.
So a<<2 is 0011 1100 = 0*2^7+0*2^6+1*2^5+1*2^4+1*2^3+1*2^2+0*2^1+0*2^0 = 1*2^5+1*2^4+1*2^3+1*2^2 = 32+18+8+4=60
hence a<<2 = 60
Now:
checker & (1<<val),
will always be greater then 0, if 1 is already present at 1<<val position.
Hence we can return false.
Else we will assign checker value of 1 at 1
I've been working on the algorithm and here's what I noticed that would also work. It makes the algorithm easier to understand when you exercise it by hand:
public static boolean isUniqueChars(String str) {
if (str.length() > 26) { // Only 26 characters
return false;
}
int checker = 0;
for (int i = 0; i < str.length(); i++) {
int val = str.charAt(i) - 'a';
int newValue = Math.pow(2, val) // int newValue = 1 << val
if ((checker & newValue) > 0) return false;
checker += newValue // checker |= newValue
}
return true;
When we get the value of val (0-25), we could either shift 1 to the right by the value of val, or we could use the power of 2s.
Also, for as long as the ((checker & newValue) > 0) is false, the new checker value is generated when we sum up the old checker value and the newValue.
public static boolean isUniqueChars(String str) {
int checker = 0;
for (int i = 0; i < str.length(); ++i) {
int val = str.charAt(i) - 'a';
if ((checker & (1 << val)) > 0)
return false;
checker |= (1 << val);
}
return true;
}
1 << val uses right shift operator. Let us say we have character z. ASCII code of z is 122. a-z is 97- 122 = 25. If we multiply 1*(2)^25 = 33554432. Binary of that is 10000000000000000000000000
if checker has 1 on its 26th bit then this statement if ((checker & (1 << val)) > 0) would be true and isUniqueChar would return false.
otherwise checker would turn it's 26th bit on. |= operator(bitwise or and assignment operator) does checker bitwise OR 10000000000000000000000000. Assigns the result to checker.

Categories

Resources