Looking at some code written by another developer, I came across this:
for($i=1; $i<=30; $i++)
{
if($i&1)
$color = '#fff';
else
$color = '#bbb';
}
This $color variable is used for row background colour later in the code. The alternating colours work fine.
If I was writing this, I would have used the modulus operator (%) rather than the bitwise (&) operator.
Why does the bitwise operator work in this case? Is there any advantage of using this method rather than the modulus operator?
The & operator does a bitwise comparison on the number. So if you do
$i & 1
it will then tell you if the '1' flag is set, such as in binary:
001010111010
The last number is the '1' flag (remember, binary goes 1, 2, 4, 8 etc. in reverse order), which in this case is set to 0.
Since 1 is the only odd flag in binary, it will tell you if the number is odd or even.
if $i is 3 for example, then in binary it will be 011 - the last number is a 1 (the 1 flag) and thus $i & 1 will be true.
if $i is 4 for example, then in binary it will be 100 - the last number is a 0 (the 1 flag) and thus $i & 1 will be false.
It works because the first bit is always 1 if the number is odd and 0 if the number is even.
1
10
11
100
101
110
111
etc.
In theory bitwise operation is faster than the modulus operation, but it's possible that the interpreter would have optimized the modulus operation down to bitwise operation anyway.
Why the other developer used it, we can only guess: out of habit, copy-pasted from somewhere, doesn't know about the modulus operator, showing off, wanting to optimize...
Related
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Reference - What does this symbol mean in PHP?
When I was reading this php page, I was not sure what & is doing in $var & 1.
function odd($var)
{
// returns whether the input integer is odd
return($var & 1);
}
Is it returning a reference? I am not sure.
If you can explain it or direct me a php page, I will appreciate it.
Thanks in advance.
It's a bitwise-AND operation. All odd numbers have LSB (least significant bit set to 1), even numbers - 0.
So it simply "ANDs" two numbers together. For example, 5. It is represented as 101 in binary. 101 & 001 = 001 => true, so it is odd.
It is performing bitwise ANDing.
That is a bitwise operator
$a & $b Bits that are set in both $a and $b are set.
In this case, return($var & 1); will do a bitwise AND against 0000....0001 returning 1 or 0 depending on the last bit of $var.
If the binary representation of a number ends in 0, it is even (in
decimal).
If the binary representation of a number ends in 1, it is
odd (in decimal).
& is the bitwise and operator. In this case it will return 1 if $var is odd, 0 if $var is even.
What's the correct way to handle two distinct values being stored in one byte of data. I have a byte that contains two nibbles each containing their own data. I want to read the top nibble and the bottom nibble into their own variables.
11110000 = High 4 bits throttle, to be read into $throttle, and should be a value from 0 to 15.
00001111 = Low 4 bits brake, to be read into $brake, and should be a value from 0 to 15.
Don't forget, drivers can apply the throttle and the brake at the same time, so you might get a value like 11000111. I've myself come up with a solution for the high 4 bits, and it's as simple as pushing the lower 4 bits out of the way with the >> (bit shift right) operator 4 times. $Throttle = $ThrBrk >> 4, but as I can't do that in one move for the lower four bits it looks kinda bad in my source code.
Use ANDoperators for both and shift the top nibble four bits to the right.
$brake = $value & 0x0F;
$throttle = ($value & 0xF0) >> 4;
Check out the & operator, which is a bitwise AND. To get the first (least significant bit), do this:
$lsb = $bits & 1;
So, to get the whole "nibble":
$break = $bits & 15;
What does the << Operator mean in php?
Example:
$t = 5;
$foo = 1 << ($t);
echo($foo);
echo produces: 32
It is the bitwise shift operator. Specifically, the left-shift operator. It takes the left-hand argument and shifts the binary representation to the left by the number of bits specified by the right-hand argument, for example:
1 << 2 = 4
because 1 (decimal) is 1 (binary); left-shift twice makes it 100 which is 4 in decimal.
1 << 5 = 32
because 100000 in binary is 32 in decimal.
Right shift (>>) does the same thing but to the right.
Easy trick to get result of the left shift operation, e.g.
15 << 2 = 15 * (2*2) = 60
15 << 3 = 15 * (2*2*2) = 120
15 << 5 = 15 * (2*2*2*2*2) = 480
and so on..
So it's:
(number on left) multiplied by (number on right) times 2.
Same goes for right shift operator (>>), where:
(number on left) divided by (number on right) times 2
"<<" is a bit-shift left. Please review PHP's bitwise operators. http://php.net/manual/en/language.operators.bitwise.php
A more in-depth explanation:
This means multiply by two because it works on the binary level. For instance, if you have the number 5 in binary
0101
and you bit-shift left once to (move each bit over one position)
1010
then your result is 10. Working with binary (from right to left) is 2^0, 2^1, 2^2, 2^3, and so on. You add the corresponding power of two if you see a 1. So our math for our new result looks like this:
0 + 2^1 + 0 + 2^3
0 + 2 + 0 + 8 = 10
It is the binary shifting operator:
http://php.net/manual/en/language.operators.bitwise.php
<< Bitwise left shift. This operation shifts the left-hand operand’s bits
to the left by a number of positions equal to the right operand,
inserting unset bits in the shifted positions.
>> Bitwise right shift. This operation shifts the left-hand operand’s bits
to the right by a number of positions equal to the right operand,
inserting unset bits in the shifted positions.
NOTE: It’s also interesting to note that these two provide an easy (and very fast)
way of multiply/divide integers by a power of two. For example: 1<<5 will give 32 as a result.......
Consider:
echo 50 >> 4;
Output:
3
Why does it output 3?
50 in binary is 11 0010, shift right by 4 yields 11 which is equal to 3.
See PHP documentation and Wikipedia.
As documented on php.org, the >> operator is a bitwise shift operator which shifts bits to the right:
$a >> $b - Shift the bits of $a $b steps to the right (each step means "divide by two")
50 in binary is 110010, and the >> operator shifts those bits over 4 places in your example code. Although this happens in a single operation, you could think of it in multiple steps like this:
Step 1 - 00011001
Step 2 - 00001100
Step 3 - 00000110
Step 4 - 00000011
Since binary 11 is equal to 3 in decimal, the code outputs 3.
Arithmetic shift right.
The >> operator is called a binary right shift operator.
Shifting bits to the right 4 times is the same as dividing by two, four times in a row. The result, in this case would be 3.125. Since 50 is an int, bit shifting will return the floor of this, which is 3.
Put another way, 50 is 0b110010 in binary. Shifted 4 times we have 0b11, which is 3 in decimal.
>> is the binary right-shift operator.
Your statement shifts the bits in the numeric value 50 four places to the right. Because all integers are represented in two's complement, this equals 3. An easy way to remember this is that one shift to the right is the same as dividing by 2, and one shift to the left is the same as multiplying by 2.
It's called a right shift.
'The bits of the left operand are shifted right by the number of positions of the right operand. The bit positions vacated on the left are filled with the sign bit, and bits shifted out on the right are discarded.'
Information can be found on it here:
http://php.comsci.us/etymology/operator/rightshift.php
It shifts the bits down four places.
50 in binary is 110010.
Shifted down four places is 11, which is 3.
For your convenience, one of the fastest ways to calculate the outputted value from a bitwise shift is to multiply or divide by 2.
For example echo 50 >> 4;
Given that this is a bitwise right, it literally means that the value will be decrease, then we can get the output by divide 50 for 2 and 4 times.
echo 50 >> 4; // 50/(2*2*2*2) ~ 3.
Given that (from) 48 -> (to) 63/16(2*2*2*2), the result will be more than 2 and less than 4. Then
echo 48 >> 4; // 48/(2*2*2*2) ~ 3.
echo 63 >> 4; // 63/(2*2*2*2) ~ 3.
However, when bitwise left, the result will be totally different as it multiplies by 2 with n times:
If echo 50 << 4; // 50*(2*2*2*2) ~ 800
If echo 51 << 4; // 51*(2*2*2*2) ~ 816
Live example: https://3v4l.org/1hbJe
What does this code mean and what are other ways accomplish the same without using bit shifting?
if ($n & ($n - 1))
That formula checks to see whether a number is a power of 2 (if your condition as written is true, then the number is not a power of two).
Stated another way, your test checks to see whether there is more than one "1" bit set in the binary representation of $n. If there is zero or only one bit set, then your test will be false.
It is by far the most efficient way to determine that property.
First, this code is valid PHP, so your title is poor.
Second, the binary arithmetic going on looks something like this:
42 = 101010
&
41 = 101001
-----------
40 = 101000
Like Greg states this is the fastest way to check for a power of 2 number, but the code you've given checks to see if the number is not a power of 2. This can easily be ascertained by PHP's policy of: any non-null/non-zero value is true.
When we use ($n & ($n - 1)) then it converts $n & ($n-1) to its binary values and does binary AND operation.
Example
3 = 0011
4 = 0100
5 = 0101
3 = 0011
&
4 = 0100
------------
0
4 = 0100
&
5 = 0101
-----------
100
To check if given number is power of 2 or not we alway use formulae
($n & ($n - 1) == 0) which means ANDing of $n & $n-1 is equals to 0 or not.
Online AND Operation Calculator