How can I parse a configuration value with PHP which is a number and a total of other numbers.
One example of this is:
1 -> Logging Enabled
2 -> Error Reporting Enabled
4 -> E-Mail Reporting Enabled
3 -> Logging + Error Enabled
5 -> Logging + E-Mail Enabled
You don't just have a sum -- you have yourself a set of flags, or a bit field, with each flag represented by one bit.
$logging = !!($cfgval & 1);
$errorReport = !!($cfgval & 2);
$emailReport = !!($cfgval & 4);
The "!!" just ensures that numbers that aren't 0 (ie: numbers with the specific bit set) end up as the same "true" value that the rest of PHP uses, so stuff like ($logging == true) always works as expected. It's not required, but i highly recommend you convert the value to a boolean somehow; (bool) would work as well, even if it is 3 times as many characters. :)
As long as you keep the numbers as powers of two (1, 2, 4, 8, 16, 32...), it's easy to extend this up to 31-32 different flags (integers are 32 bits in size, but the top bit is a sign bit which acts kinda funny if you don't know about "two's complement" math).
Related
I was reviewing some PHP code and stumbled across this:
if(($this->int & 0b111111111) === 0){ //blah
I was very puzzled at where 0b111111111 came from. What is this and how was it generated? I var_dumped it and it turned out to be 511, but why was this used instead of the number 511? Where did it come from?
It is an integer using binary notation, and equals to 511 in decimal notation.
The coder is using it as mask for a binary AND (the &).
The test equals 0 only if $this->int == 0, as the binary AND operator compares each bit of the binary value, and returns 1 at the corresponding position where both the left and right numbers have a 1 at that position.
I have no special idea of the use here though: depending on the context, it could be for consistency. Or it's just "clever code" for writing
if($this->int === 0){ // Dumber blah
I need to use two functions, one sums the values of checkboxes and I put that value into a cookie for one of many checkboxes used for a search page on a website.
The second function checks if the bit is set and I have no idea what this function is supposed to be doing. I know what it should do but I don't see it actually doing anything in the function.
All of the values are powers of 2 and it is supposed to see if the summed number contains that power of two. Below is the function:
function isBitSet($power, $decimal)
{
if((pow(2,$power)) & ($decimal))
{
return 1;
}
else
return 0;
}
& is the bitwise AND operator (not to be confused with &&, which is a comparison operator)! & compares the thing on its left and the thing on its right, bit by bit, and only outputs a 1 for each bit where BOTH inputs bits had a 1. I'll show an example:
In the following example, the top number is pow(2, $power), where $power = 3. It's written in binary form to make it clearer: doing 2 to the power of 3 has shifted a binary 1 right 3 places.
00001000 <- this is pow(2, 3)
& 01101010 <- this is your $decimal (in binary form)
========
= 00001000
You see? All the output bits are 0, except where BOTH input bits were 1.
What we have done is we have used pow(2, 3) as a MASK: it has cleared EVERY bit to 0, except the one we are interested in (bit 3). That bit will be 1 if $decimal contains this particular power of 2, otherwise it will be 0:
$decimal contains that power of 2 -> result will be 00001000
$decimal does not contain that ^2 -> result will be 00000000
Since any non-zero integer evaluates to true in PHP, the if will occur if that bit is set (i.e. $decimal contains that power of 2), and the else will occur if that bit is not set (because the & will result in an output of 00000000).
Please comment if you need any of that clarified. Hope it helps.
Trying to understand this entry in the php manual on debug_backtrace.
I don't understand what they mean by "this parameter is a bitmask for ...."
I have done web searches on bitmasks and my head is spinning round so I have decided I don't really want to learn the detail about it but just to know how I can supposed to add the options to that function.
Do I put in both options as in
debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT, DEBUG_BACKTRACE_IGNORE_ARGS)
if I want both and one of them if I only want that one?
Be aware that those 2 constants (DEBUG_BACKTRACE_PROVIDE_OBJECT, DEBUG_BACKTRACE_IGNORE_ARGS) are different in meaning. While DEBUG_BACKTRACE_PROVIDE_OBJECT provides an additional object when present, DEBUG_BACKTRACE_IGNORE_ARGS strips the args when present.
Since the most common use-case for these constants is to reduce memory usage, the way with least memory-consumption is:
debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
NOT
// false friend!
debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT | DEBUG_BACKTRACE_IGNORE_ARGS);
It overrides the default of DEBUG_BACKTRACE_PROVIDE_OBJECT and additionally ignores DEBUG_BACKTRACE_IGNORE_ARGS.
The constants will have values of 2^n in decimal, or (10)^n in binary. For example - 1, 10, 100, 1000, etc (in binary).
Say a=001, b=010, c=100:
You can do bitwise or on, for example, a and b. This will mean each bit will be 'turned on' if the same bit in either a or b is 'on'.
a | b == 011
This is a bitmask. The bitmask is checked for the inclusion of a by
bitmask & a != 0
Which is
011 & 001 == 001 != 0
However, because c is not in the bitmask:
bitmask & c == 011 & 100 == 0
So, to include both a and b in the bitmask, you use the binary or operator.
debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT | DEBUG_BACKTRACE_IGNORE_ARGS);
It means you combine options with the bitwise OR operator: |.
For example:
debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT | DEBUG_BACKTRACE_IGNORE_ARGS);
For more details about bitmasks: http://en.wikipedia.org/wiki/Mask_(computing)
I've run into a problem whilst converting some C code to PHP, specifically in the use of the right-shift operator.
edit: in the following examples, bit = 0;
Original C code:
p->param->outBits[bytePtr++] |= codeword >> (9 + bit);
PHP code:
$outBits[$bytePtr++] |= $codeword >> (9 + $bit);
If I start with codeword being 130728, in C I get the expected result of -1. In PHP I get 255. I understand this is something to do with arithmetic/logical shift differences, and the negative sign not being introduced as a result of the MSBs staying at zero.
Is there a "quick" way of doing the above in PHP that doesn't involve the shifting? eg via basic arithmetic or similar, that will give me the expected answer?
Your problem is that PHP doesn't have a type byte, it only has integer which usually is 32 bits (not 8), so if you really need negative value there (the bits are correct anyway, because unsigned 255 is the same as signed -1), then you should probably add the missing 24 ones or use arithmetics to restore the negative value (255 is -1, 254 is -2 and so on i.e. 256 - x = -x).
I'm having trouble calculating roots of rather large numbers using bc_math, example:
- pow(2, 2) // 4, power correct
- pow(4, 0.5) // 2, square root correct
- bcpow(2, 2) // 4, power correct
- bcpow(4, 0.5) // 1, square root INCORRECT
Does anybody knows how I can circumvent this? gmp_pow() also doesn't work.
I'm not a PHP programmer but looking at the manual it says you have to pass them in as strings i.e.
bcpow( '4', '0.5' )
Does that help?
Edit: The user contributed notes in the manual page confirm that it doesn't support non-integer exponents.
I did come across this discussion of a PHP N-th root algorithm after a quick search so perhaps that's what you require.