This RFC is to discuss the addition of 2 new operators to the core, a logical left shift and a logical right shift.
The currently implemented left and right shift operators (<<
and >>
respectively) perform arithmetic shifts. I am proposing the introduction of a pair of logical shift operators which perform their operations on arbitrary length strings.
The problem can be seen by trying to shift -1
(0xFFFFFFFF
on 32 bit, 0xFFFFFFFFFFFFFFFF
on 64 bit). If we try -1 >> 1
, we get back -1
again. This is due to the shift being arithmetic. If we try -1 >> 2
, we will still get -1
.
Additionally, the current shifts only work on strings when the string is parsable as a number. So “2” >> 1
yields 1
instead of the expected logical value of 0x19
.
At present, if you want to do a logical shift on a string, you need to iterate over the string and apply the shift to each part of it (where the part is less than 4 bytes long, to prevent issues on 32 bit systems). For example:
For example, to implement a logical left shift currently requires something like this (this example could be optimized, but the basics of it are there):
$mask = (0xff << (8 - $bits)) & 0xff; $state = 0; $length = strlen($data); for ($i = $length - 1; $i >= 0; $i--) { $tmp = ord($data[$i]); $result .= chr(($tmp << $bits) | $state); $state = ($tmp & $mask) >> (8 - $bits); } return strrev($result);
Other bitwise operators do operate properly on strings (such as XOR - ^
, AND - &
and OR - |
). So it would be complete to add support for shifting strings.
I propose the addition of two new operators which will perform a logical shift. The selection of the operators is a little bit more difficult as <<<
is already taken by heredoc. Perhaps something like b<<
...
Example:
$foo = “a long string” {operator} 1;
Would yield a string with the following bits:
0xc240d8dedcce40e6e8e4d2dcce
- Added note about <<< being used by heredoc already.