Bitwise operations in PHP?
You could use it for bitmasks to encode combinations of things. Basically, it works by giving each bit a meaning, so if you have 00000000
, each bit represents something, in addition to being a single decimal number as well. Let's say I have some preferences for users I want to store, but my database is very limited in terms of storage. I could simply store the decimal number and derive from this, which preferences are selected, e.g. 9
is 2^3
+ 2^0
is 00001001
, so the user has preference 1 and preference 4.
00000000 Meaning Bin Dec | Examples
│││││││└ Preference 1 2^0 1 | Pref 1+2 is Dec 3 is 00000011
││││││└─ Preference 2 2^1 2 | Pref 1+8 is Dec 129 is 10000001
│││││└── Preference 3 2^2 4 | Pref 3,4+6 is Dec 44 is 00101100
││││└─── Preference 4 2^3 8 | all Prefs is Dec 255 is 11111111
│││└──── Preference 5 2^4 16 |
││└───── Preference 6 2^5 32 | etc ...
│└────── Preference 7 2^6 64 |
└─────── Preference 8 2^7 128 |
Further reading
http://www.weberdev.com/get_example-3809.html- http://stu.mp/2004/06/a-quick-bitmask-howto-for-programmers.html
- Why should I use bitwise/bitmask in PHP?
- http://en.wikipedia.org/wiki/Mask_%28computing%29
How To Test PHP Bitwise Function Input Parameters
I think you'll find that flags like this are normally defined as powers of 2, e.g.:
define('FLAGA',1);
define('FLAGB',2);
define('FLAGC',4); /* then 8, 16, 32, etc... */
As you rightly stated, these can be combined by using a bitwise OR operator:
foo('test.txt',FLAGA | FLAGB | FLAGC);
To test these flags inside your function, you need to use a bitwise AND operator as follows:
function foo($sFile, $vFlags) {
if ($vFlags & FLAGA) {
// FLAGA was set
}
if ($vFlags & FLAGB) {
// FLAGB was set
}
//// etc...
}
bitwise operator in PHP
In bits:
- 01
- 10
- 11
The &
operator returns all bits set to 1 in both numbers. So:
- 1 & 2 -> 01 & 10 -> 00 == 0
- 2 & 3 -> 10 & 11 -> 10 == 2
Bitwise operations on boolean values
Answer 1
Parts of a boolean expressions (||
, &&
, !
, ...) are only evaluated if needed (from left to right):
if ($a | func()) { } // func is always called
if ($a || func()) { } // func is not called if $a is true,
// because expression is true whatever func will return
if ($a && func()) { } // func is not called if $a is false,
// because expression is false whatever func will return
func() || exit(); // exit() will be called if func() returns false
Take a look at the documentation: http://php.net/manual/en/language.operators.logical.php
Answer 2
~true
seems not to be meaningful: true
is 0x00...01
and ~true
will be 0xff...fe
and not false
0x000...0
:
var_dump(~((int)true)); // prints: int(-2)
echo dechex(~((int)true)); // prints: fffffffffffffffe
Use !
-operator instead:
var_dump(!true); // prints: bool(false)
Résumé
Use bitwise operators only if you need to change bits.
Bitwise OR operator in PHP, Bug or Feature?
That's due to the bitwise OR operator. It interprets each string as binary and performs the operation.
01101000 // 'h'
00101111 // '/'
-- OR --
01101111 // 'o'
^ looking at the first character
Further Explanation
PHP seems to loop through each character of a string and apply the bitwise operator to it.
So what actually happens is more like:
"h" | "/" -> "o"
"t" | "" -> "t"
"t" | "" -> "t"
"p" | "" -> "p"
...
Any empty string in bitwise operations would end up being all 0
s in binary, so if we just look at the first two characters for comparison
// character at index [0]
"h" -> 01101000 (104)
"/" -> 00101111 (47)
-- OR --
"o" -> 01101111 (111)
// character at index [1]
"t" -> 01110100 (116)
"" -> 00000000 (0)
-- OR --
"t" -> 01110100 (116)
How bitwise operator 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
C & PHP: Storing settings in an integer using bitwise operators?
You sure can do it in PHP.
Let's say you have four booleans you want to store in a single value. That means we need four bits of storage space
0000
Each bit, when set individually, has a unique representation in decimal
0001 = 1 // or 2^0
0010 = 2 // or 2^1
0100 = 4 // or 2^2
1000 = 8 // or 2^3
A common way to implement this is with bit masks to represent each option. PHP's error levels are done this way, for example.
define( 'OPT_1', 1 );
define( 'OPT_2', 2 );
define( 'OPT_3', 4 );
define( 'OPT_4', 8 );
Then when you have an integer that represents 0 or more of these flags, you check with with the bitwise and operator which is &
$options = bindec( '0101' );
// can also be set like this
// $options = OPT_1 | OPT_3;
if ( $options & OPT_3 )
{
// option 3 is enabled
}
This operator works as such: only bits that are set in both operands are set in the result
0101 // our options
0100 // the value of OPT_3
----
0100 // The decimal integer 4 evaluates as "true" in an expression
If we checked it against OPT_2
, then the result would look like this
0101 // our options
0010 // the value of OPT_2
----
0000 // The decimal integer 0 evaluates as "false" in an expression
When should I use a bitwise operator?
Bitwise |
and &
and logical ||
and &&
are totally different.
Bitwise operators perform operations on the bits of two numbers and return the result. That means it's not a yes or no thing. If they're being used in conditional statements, they're often used as part of logical comparisons. For example:
if ($x & 2 == 2) {
// The 2^1 bit is set in the number $x
}
Logical operators compare two (or more) conditions/expressions and return true or false. You use them most commonly in conditional statements, like if
and while
. For example:
if ($either_this || $or_this) {
// Either expression was true
}
How to use the PHP bitwise AND operator with Javascript
Well thanks to the comments of those who responded, and looking and entering the topic, I reviewed the documentation of both languages and then what I did was divide the strings, and do the and - &
to each pair of their position and the result it was similar to php.
here as I did.
const a = '100110100011111000100110';
const b = '111111111111111111111110';
function andBin (one, two) {
const _a = one.split('')
const _b = two.split('')
let result = ''
_a.map((e, i) => {
result += Number(e) & Number(_b[i])
})
return result
}
andBin(a, b) // 100110100011111000100110
ready. resolved, thank you all very much.
Related Topics
How to Create Codeigniter Language Files from Database
How to Set 777 Permission on a Particular Folder
Permission Denied with Bash.Sh to Run Cron
Trying to Access Array Offset on Value of Type Null
Combine PHP Prepared Statments with Like
PHP Simplexml Attributes Are Missing
Invalid JSON Parsing Using PHP
Bad Request. Connecting to Sites via Curl on Host and System
How to Connect SQL Server with PHP Using Xampp
How to Add Dynamic Dropdown List Column on Laravel 5.3 Registration
Simplexml: Working with Xml Containing Namespaces
How to Construct a Cross Database Query in PHP
Int Variable with Leading Zero
How to Pass Custom Type Array to Postgres Function
How to Open a File from Line X to Line Y in PHP
PHP Readdir Problem with Japanese Language File Name
Can't Decrypt Using Pgcrypto from Aes-256-Cbc But Aes-128-Cbc Is Ok