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
Related
Operations on bits.
How to take 2 bits from byte like this:
take first 2 from 12345678 = 12;
Make new byte = 00000012
For example as asked in discussion by jspit :
$char = 'z'; //is 122, 0111 1010
$b = $char & '?'; // ? is 63, 0011 1111
echo $b; //$b becomes 58 and shows ':'
//if integer used you get:
$b = $char & 63;// 63 is 0011 1111 as '?' but $char is string and you get 0 result:
echo $b; //$b becomes 0 because conversion to integer is used from string and $char becomes 0 and get 0 & 63 = 0, and here is error.
For clearance operation is on bits not on bytes, but bits from bytes.
'string' >> 1 not work, but this is second problem.
Codes of char You can check on my site generating safe readable tokens, with byte template option on. Site is in all available languages.
I think I found good answer here:
how to bitwise shift a string in php?
PS. Sorry I cant vote yours fine answers but I have no points reputation here to do this ;)...
I hope you understand bits can only be 0 or 1, I'm assuming when you say "12345678" you're just using those decimal symbols to represent the positions of each bit. If that is the case, then you're looking for bitwise operators.
More specifically:
$new = $old >> 6;
This bitwise shift operation will shift all bits 6 positions to the right, discarding the 6 bits that were there before.
You can also use an or operation with a bitmask to ensure only 2 bits remain, in case the variable had more than 8 bits set:
$new = ($old >> 6) | 0b00000011;
function highestBitsOfByte(int $byte, int $count = 2):int {
if($count < 0 OR $count > 8) return false; //Error
return ($byte & 0xFF) >> (8-$count);
}
$input = 0b10011110;
$r = highestBitsOfByte($input,2);
echo sprintf('%08b',$r);
The integer number is limited to the lowest 8 bits with & 0xFF. Then the bits are shifted to the right according to the desired length.
example to try: https://3v4l.org/1lAvO
If there is a character as input and the fixed number of 2 bits is required, then this can be used:
$chr = 'z'; //0111 1010
$hBits = ord($chr) >> 6;
echo sprintf('%08b',$hBits); //00000001
I'm new to PHP
I was taking coding challenge and I stumbled on this
piece of code :
// check whether a given positive integer is a power of two.
The solution
function is_Power_of_two($n)
{
if(($n & ($n - 1)) == 0)
{
return "$n is power of 2";
}
else
{
return "$n is not power of 2";
}
}
print_r(is_Power_of_two(4)."\n");
print_r(is_Power_of_two(128)."\n");
print_r(is_Power_of_two(16)."\n");
In the if section, what is happening there ?
let's say $n = 2
2 & 2 - 1 == 0 // replaced $n with num
2 & 1 == 0 ? // results , What ?
EDIT :
So basicly
& isn't a logical operator
It is a bitwise Operator
Bitwise operators allow evaluation and manipulation of specific bits
within an integer.
You can check this video that I found very helpful it will show you how bit's work and how you can work with bitwise
https://www.youtube.com/watch?v=2U-bh4gSn1k
And thanks to : kollol
now I get why the solution code return only the power of two values
Also thanks to :
lars-stegelitz
kiko-software
if both digits are same vertically then the value will be 1, 0 otherwise
for example
2 & 16 = (binary of 2) & (binary of 16)
00010 & 10000
= 00000 = 0
(2) 00010
(16) 10000
------------------
00000
now suppose
2 & 18 = (binary of 2) & (binary of 18)
00010 & 10010
(2) 00010
(18) 10010
----------------------
00010 = not 0
logic is all the numbers which are power of two will always get a 0 in bitwise and operation with 2. Rest will not .
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.
<?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
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.