This question already has answers here:
What are bitwise operators?
(9 answers)
Closed 7 years ago.
I dont get how the following codes work?
function odd($var){
return ($var & 1);
}
echo odd(4); /* returns and print 0 */
echo odd(5); /* returns and print 1 */
this function returns true if argument is an odd number
and returns false if argument is an even number. How it works ?
Odd numbers in binary always have a least-significant bit (LSB) of 1. That is why your code
function odd($var){
return ($var & 1);
}
returns true on odd numbers. Here are your examples from your question:
(decimal) 4 & 1 = (binary) 100 & 001 = (binary) 000 = (decimal) 0 = false
(decimal) 5 & 1 = (binary) 101 & 001 = (binary) 001 = (decimal) 1 = true
Another way to think of it is
100 (decimal 4) - an even number
AND 001 (decimal 1)
= 000 (decimal 0) - return false
and
101 (decimal 5) - an odd number
AND 001 (decimal 1)
= 001 (decimal 1) - return true
bitwise comparison already says what it does: it compares the numbers bit by bit.
If we take 4 bits, the bit representation of 4 is: 0100. The bit representation of 5 is 0101. When we compare this with & (and), it returns the bits which are both set.
0100 & 0001 = 0000 (no bits are the same)
0101 & 0001 = 0001 (only Least Significant Bit (LSB) is 1)
It is masking off all bits except 0. & is the and operator. And 1 is 000000000001 in binary. So it works as it is named.
Related
I'm trying to understand this code in the company's system that I am working in but this doesn't make any sense for me.
$k = 48;
if (($k & 2) > 0) {
echo "2 is true";
}
echo "<br />";
if (($k & 4) > 0) {
echo "4 is true";
}
echo "<br />";
if (($k & 8) > 0) {
echo "8 is true";
}
echo "<br />";
if (($k & 16) > 0) {
echo "16 is true";
}
echo "<br />";
if (($k & 32) > 0) {
echo "32 is true";
}
When $k is 10 or 11, both 2 and 8 is true.
When $k is 12 or 13, both 4 and 8 is true.
Please help me figure this out
This code is simply checking if certain bit positions are set in some value $k. See how bitwise airthmetic works.
In the code you've sent us, it doesn't have much context. However, this is a typical pattern for checking values in a bitmask.
In general, however, the > 0 is unnecessary (since anything !0 typically == true).
It is important to note that when I say bit positions, I mean of the binary number. That is, $k & 32 does not check bit number 32, it instead checks the 6th most significant bit (32d == 0b100000).
Short example
Consider the last statement. We already determined that decimal 32 looks like 100000 in binary. Now say that we want to check whether or not the 6th bit is set in some number 33. 33 is represented as 0b100001 in binary. Now we take the bitwise and which works much like multiplication that we're used to seeing in base 10 (i.e. decimal).
0b100000 <--- decimal 32
&
0b100001 <--- decimal 33
--------
0b100000 <--- Result is > 0 and, therefore, this value has the 6th bit set
Now, let's retry this example with a different number. How about decimal 15.
0b100000 <--- decimal 32
&
0b001111 <--- decimal 15
--------
0b000000 <--- Result == 0 and, therefore, the 6th bit is not set
Now, this & (not to be confused with logical and which is represented as &&) works for multiple bits as well. Say you want to check for bits 6 and 4, then you would want to use 0b101000 (decimal 40), but depending on what you wanted to test (i.e. exactly those bits or just one of those bits), your conditional may change.
Just a little bit more
From a style standpoint it is important to note that these masks are typically represented in hexadecimal instead of decimal (or binary because that would be cumbersome). This is mostly because it is somewhat unclear what binary representation a decimal number correlates to when looking at it "at-a-glance." Let us again consider decimal 32. In hexadecimal, a binary number can be represented as a hexadecimal number by simply grouping bits by 4's (from right to left). See below
0b100000 <--- decimal 32
0000 === 0x0 (hexadecimal 0)
10 === 0b0010 (implied leading 0's) === 0x2 (hexadecimal 2)
--------
0x20
As you can see, hex 20 is decimal 32 is binary 100000.
In your code there are just some bitwise AND operation which checks if some bits are set or not.
So if we take a look what's going on in the first one:
$k = 48;
if (($k & 2) > 0) {
echo "2 is true";
}
The expression ($k & 2) a bit more readable:
0011 0000 $k
0000 0010 2
------------ &
0000 0000 = 0
So if (0 > 0) is false
And another example:
if (($k & 16) > 0) {
echo "16 is true";
}
The expression ($k & 16) a bit more readable:
0011 0000 $k
0001 0000 16
------------ &
0001 0000 = 16
So if (16 > 0) is true
FYI information:
Bitwise AND operation table:
A | B | Result
--------------------
0 | 0 | 0
0 | 1 | 0
1 | 0 | 0
1 | 1 | 1
And as a reference to the manual here: http://php.net/manual/en/language.operators.bitwise.php
<?php
echo 2<<3; //Output 16
echo '---';
echo 3<<2; //Output 12
?>
Tried to find out logic. But its ends up in vain!! Can someone explain it please
The << operator is a bitwise operator. This basically means the numbers are treated as binary numbers, and the interaction is about moving bits around.
So let's have a look at the numbers and the operations:
First, 2 << 3
0b000010 // 2 in binary
0b010000 // move the bits three left, we get 16
Then 3 << 2
0b000011 // 3 in binary
0b001100 // move the bits two left, we get 12
From the manual page linked above:
Shift the bits of $a $b steps to the left (each step means "multiply by two")
So 3<<2 in effect means 3*(2^2), while 2<<3 means 2*(2^3).
The << operator is bitwise left shift.
Let's write the numbers in their binary representation
0000 0010 // 2
0000 0011 // 3
And then shift them by 3 and 2 respectively:
0001 0000 // 16
0000 1100 // 12
2 = 0b10
0b100 = 4
0b1000 = 8
0b10000 = 16
3 = 0b11
0b110 = 6
0b1100 = 12
The fist operator (<<) 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 argument. Right-shift (>>) does the same but to the right. Read more about it here http://php.net/language.operators.bitwise
This question already has answers here:
What's the function of the ~ bitwise operator (Tilde) [duplicate]
(3 answers)
Closed 9 years ago.
Consider:
php > $a = 12; // 1100
php > echo ~$a;
-13
I would expect the inverse of 1100 to be either 0011 (direct) or 11110011 (an entire byte). That would give a result to either 3 or 243. Whence cometh -13?
Again, for good measure, another unexpected result of the same type and explanation:
php > $b = 6; // 0110
php > echo ~$b;
-7
Why -7?
Look at this code:
<?php
$val = 6;
print "$val = ".decbin($val);
print "\n";
$val = ~$val;
print "$val = ".decbin($val);
It prints
6 = 110
-7 = 11111111111111111111111111111001
At first you have 110. As my php uses 32 bits, after inverting all the bits, we get this huge number. As the 1-st bit is 1, php interprets it as a negative value, stored, using two's-complement representation. To find out, the modulus of the negative value, stored in this notation, we
invert the digits:
110
add one to the result:
111
which gives us 7
So, the value is -7
http://www.cs.cornell.edu/~tomf/notes/cps104/twoscomp.html
Why -7?
6 is 00000000000000000000000000000110, so ~6 is ~00000000000000000000000000000110, and that's equal to 11111111111111111111111111111001. Because a signed datatype is used, the first bit indicates whether the number is positive or negative (positive = 0 and negative = 1). Because it is Two's complement, you should convert the binary number to decimal using this way:
Invert the binary number. You get 00000000000000000000000000000110
Convert 00000000000000000000000000000110 (a positive binary number) to a decimal number. You get 6
Add 6 up with one: you get 7
Make it negative: you get -7
I've always used the following in order to find even and odd numbers:
if( $num % 2 ) { echo "odd"; }
if( !($num % 2) ) { echo "even"; }
But recently I stumbled upon with the following code that works exactly the same:
if( $num & 1 ) { echo "odd"; }
if( !($num & 1) ) { echo "even; }
What's the logic behind the "&" in the second method?
I went to check the PHP: Arithmetic Operators and the ampersand is not part of the options.
Thanks.
It is the bitwise-AND operator. Remember that in the computer, every integer is stored in binary form, and the lowest-significance binary digit is 2^0 == 1. So, every odd number will have the lowest binary digit = 1.
So, the bitwise AND operator compares your value bit-by-bit with the constant 1. Bits that are 1 in both operands are set to 1 in the result, but bits that are 0 in either operand are set to 0 in the result. The final result (which will be either 1 or 0) is coerced to boolean by PHP because you are using it as the clause in an if() statement.
There is a very good reason for checking evenness with & instead of %: Speed! The % operator requires a division operation so the remainder can be calculated, which is computationally much, much more expensive than just comparing the bits directly.
An example:
$num = 9; // 9 == 8 + 1 == 2^3 + 2^0 == 1001b
echo (string)($num & 1); // 1001b & 0001b = 0001b - prints '1'
$num = 10; // 10 == 8 + 2 == 2^3 + 2^1 == 1010b
echo (string)($num & 1); // 1010b & 0001b = 0000b - prints '0'
& is the binary AND.
The binary value of an odd number AND 1 will be 1, and the binary value of an even number AND 1 will be 0.
This happens because the binary value of an odd number always ends with 1 and the binary value of an even number ends with 0. So...
10101101 & 00000001 = 00000001 in the case of an odd number and,
10101100 & 00000000 = 00000000 in the case of an even number.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Understanding PHP's & operator
I was just looking at array_filter() function doc and they had the following code to return odd numbers...
<?php
function odd($var)
{
// returns whether the input integer is odd
return($var & 1);
}
?>
Why does $var & 1 return odd number? how does that work?
& is bitwise and. It acts as a mask on the bits of $var. All odd numbers end with 1
no bit &1
1 001 1
2 010 0
3 011 1
4 100 0
5 101 1
6 110 0
7 111 1
You are using a bitwise function with always returns 1 when anded with an odd number.
A few examples:
11 = 3
01 = 1
----
01 = odd -- return 1 (true)
100 = 4
01 = 1
-----
000 = even -- return 0 (false)
One more:
10101 = 21
01 = 1
-------
00001 = odd -- return 1 (true)
That function return 1 if var is an odd number, 0 otherwise. "&" is the AND binary operator, so it considers the last binary digit of a number.
For example:
5 in binary is 101 -> 101 & 1 = 1 -> odd number.
8 in binary is 1000 -> 1000 & 1 = 0 -> even number.