Table of Contents

Request for Comments: Add a Logical Shift Operator For Strings

Introduction

This RFC is to discuss the addition of 2 new operators to the core, a logical left shift and a logical right shift.

Why do we need new operators?

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.

Proposal

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

Changelog

- Added note about <<< being used by heredoc already.