Can you please explain this code snippet from HashMap constructor specifically the line
capacity <<= 1:
// Find a power of 2 >= initialCapacity
198 int capacity = 1;
199 while (capacity < initialCapacity)
200 capacity <<= 1;
It is equivalent to capacity = capacity << 1;.
That operation shifts capacity's bits one position to the left, which is equivalent to multiplying by 2.
The specific code you posted finds the smallest power of 2 which is larger than initialCapacity.
So if initialCapacity is 27, for example, capacity will be 32 (2^5) after the loop.
Just like var += 1 is about equivalent to var = var + 1, what you see here (var <<= 1) is about equivalent to var = var << 1, which is "set var to be the result of a 1-position binary left-shift of var."
In this very specific case, it's actually a slightly (runtime) faster way of expressing capacity *= 2 (because a bitwise left-shift of 1 position is equivalent to a multiplication by 2).
It is equivalent of
capacity = capacity << 1;
which shifts bits in capacity one position to the left (so i.e. 00011011 becomes 00110110).
every time this comes out of the loop the value of 'capacity' goes 2 raised by a power higher.
like initially it is 1 i.e.2^0; the operation(capacity <<= 1) for the first time makes it 2^1 and then 2^2 and so on.
May be you would like to see the more on it at http://www.tutorialspoint.com/java/java_basic_operators.htm
Related
I'm looking at the way the Java Random library generates an integer given an upper bound, but I don't quite understand the algorithm. In the docs it says:
The algorithm is slightly tricky. It rejects values that would result
in an uneven distribution (due to the fact that 2^31 is not divisible
by n). The probability of a value being rejected depends on n. The
worst case is n=2^30+1, for which the probability of a reject is 1/2,
and the expected number of iterations before the loop terminates is 2.
But I really don't see how this implementation takes this into account, specifically the while condition in the code. To me it seems that this would (almost) always succeed with 50% success rate. Especially when looking at very low values for bound (which I think is used a lot when imposing a bound). It seems to me like the condition in the while is just checking the sign of bits, so why bother with the line they use?
public int nextInt(int bound) {
if (bound <= 0)
throw new IllegalArgumentException("bound must be positive");
if ((bound & -bound) == bound) // i.e., bound is a power of 2
return (int)((bound * (long)next(31)) >> 31);
int bits, val;
do {
bits = next(31);
val = bits % bound;
} while (bits - val + (bound-1) < 0);
return val;
}
Note that bits - val + (bound-1) < 0 is actually checking whether bits - val + (bound-1) overflows. bits is always equal to or greater than val, and bound is always positive, so there is no way for the LHS to be positive under normal circumstances.
We can think of the < 0 as > Integer.MAX_VALUE.
Let's plot a graph of bits - val + (bound - 1). I have made one on desmos here. Let's say bound is 100 (small bound):
The x axis is bits and y axis is bits - val + (bound-1), and I have added lines on both the x and y axes to indicate Integer.MAX_VALUE. Note that bits is bounded by Integer.MAX_VALUE.
At this scale, you can see that bits - val + (bound-1) seems to never overflow. If you zoom a lot, you'll see:
Note that there is a tiny range of values of bits for which bits < Integer.MAX_VALUE, but bits - val + (bound - 1) > Integer.MAX_VALUE.
For b = (1 << 30) + 1, the graph looks like:
Any b that is greater than 1 << 30 overflows. Hence the 1/2 chance of rejecting the bounds as the documentation said.
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 some code here that where x grows like big O(n), however I'm not sure why. It seems more of a logarithmic big O. Could I get some help figuring out why it grows like big O(n)? Thanks!
i = k; x = 1.0;
while (i > 1 ) {
i = (int) Math.floor( i / 2.0 );
x = x *2 ;
Complexity analysis has little to do with what value ends up in a variable, it a property of an algorithm, simplistically (for time complexity) how many steps it needs to do based on some input value.
In this case, given the input value k, your complexity is O(log N) because the division by two "halves the remaining solution space" on each iteration, along the lines of:
i = 128 64 32 16 8 4 2 1
The growth of the variable x which, as mentioned, has nothing to do with the algorithmic complexity, is to double each time through the loop.
So, you have a loop controlled by a value that halves on each iteration. And you have a variable that doubles on each iteration:
i = 128 64 32 16 8 4 2 1
x = 1 2 4 8 16 32 64 128
Hence it makes sense that the relationship between the input value and the final variable value will be a linear one, as shown by the equivalent Python code:
ctrl = 1024
other = 1
while ctrl > 0:
print('{0:4d} {1:4d}'.format(ctrl, other))
ctrl = ctrl // 2
other = other * 2
which outputs:
1024 1
512 2
256 4
128 8
64 16
32 32
16 64
8 128
4 256
2 512
1 1024
Note there that, though the final value in other is 1024, only ten "steps" were executed, since log21024 is 10.
If you're looking to optimize the problem, it looks like you're just calculating the largest bit
This can also be achieved a bit more efficiently with Integer.highestOneBit(int i)
Which is defined as
public static int highestOneBit(int i) {
// HD, Figure 3-1
i |= (i >> 1);
i |= (i >> 2);
i |= (i >> 4);
i |= (i >> 8);
i |= (i >> 16);
return i - (i >>> 1);
}
and should be running in constant time (O(1)) since it is only bit operators
How it works is by shifting the bits down while ORing it with itself, causing all of the bits past the largest to become 1, then to isolate the largest it subtracts that number shifted over to remove all the trailing 1s
I am trying to understand how java.util.Random.nextInt(int n) works and despite all the search and even debugging cannot completely understand the implementation.
It is the while loop that causes confusion:
http://docs.oracle.com/javase/7/docs/api/java/util/Random.html#nextInt(int)
int bits, val;
do {
bits = next(31);
val = bits % n;
} while (bits - val + (n-1) < 0);
I realize this is supposed to address the modulo bias, but struggling to see how.
Question: how can possibly the expression
bits - val + (n-1)
be negative given that bits value is 31 bit long, i.e. bits is always positive? If bits is positive, val is always less than bits then while condition always stays > 0...
The question has been already addressed in implementation-of-java-util-random-nextint.
Basically, we have to drop some top-most elements for bits in the range [0..2^31[ because they induce a non-uniform distribution
Mathematically we check :
bits - val + (n-1) >= 2^31
and could have wrote it as is if java had unsigned 32 bits integer arithmetics.
You are missing the value of n in your calculation. Either n is negative, bits - val -1 1 < n or otherwise N is big enough to make the integer overflow and become a negative number.
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);