/*
Unsigned right shift function, since PHP has neither >>> operator nor unsigned ints

@param a  number to be shifted (32-bit integer)
@param b  number of bits to shift a to the right (0..31)
@return   a right-shifted and zero-filled by b bits
335844
private static function urs($a, $b)
    {
        $a &= 0xffffffff;
        $b &= 0x1f;  // (bounds check)
        if ($a & 0x80000000 && $b > 0) {   // if left-most bit set
            $a = ($a >> 1) & 0x7fffffff;   //   right-shift one bit & clear left-most bit
            $a = $a >> ($b - 1);           //   remaining right-shifts
        } else {                       // otherwise
            $a = ($a >> $b);               //   use normal right-shift
        }

        return $a;
    }
565857
function _lshift($shift)
    {
        if ($shift == 0) {
            return;
        }

        $num_digits = (int) ($shift / MATH_BIGINTEGER_BASE);
        $shift %= MATH_BIGINTEGER_BASE;
        $shift = 1 << $shift;

        $carry = 0;

        for ($i = 0; $i < count($this->value); ++$i) {
            $temp = $this->value[$i] * $shift + $carry;
            $carry = MATH_BIGINTEGER_BASE === 26 ? intval($temp / 0x4000000) : ($temp >> 31);
            $this->value[$i] = (int) ($temp - $carry * MATH_BIGINTEGER_BASE_FULL);
        }

        if ($carry) {
            $this->value[count($this->value)] = $carry;
        }

        while ($num_digits--) {
            array_unshift($this->value, 0);
        }
    }
410770
public static function shift(string &$str, string $encoding = null)
    {
        $encoding = $encoding ?: mb_internal_encoding();

        $first = mb_substr($str, 0, 1, $encoding);
        $str = mb_substr($str, 1, null, $encoding);

        return $first;
    }
586459
static function shift_right($g, $shift)
  {
    if (0 == $shift)
      return $g;

    if (0 <= gmp_sign($g))
      $m = gmp_div($g, gmp_pow(self::gmp_2(), $shift));
    else // negative
    {
      $g = gmp_and($g, self::gmp_0xfs());
      $m = gmp_div($g, gmp_pow(self::gmp_2(), $shift));
      $m = gmp_and($m, self::gmp_0xfs());
      for ($i = 63; $i >= (63 - $shift); $i--)
        gmp_setbit($m, $i);

      $m = gmp_neg(gmp_add(gmp_and(gmp_com($m), self::gmp_0xfs()),
                           self::gmp_1()));
    }

    return $m;
  }
588406
private function doSub(string $a, string $b) : string
    {
        if ($a === $b) {
            return '0';
        }

        // Ensure that we always subtract to a positive result: biggest minus smallest.
        $cmp = $this->doCmp($a, $b);

        $invert = ($cmp === -1);

        if ($invert) {
            $c = $a;
            $a = $b;
            $b = $c;
        }

        $length = $this->pad($a, $b);

        $carry = 0;
        $result = '';

        $complement = 10 ** $this->maxDigits;

        for ($i = $length - $this->maxDigits;; $i -= $this->maxDigits) {
            $blockLength = $this->maxDigits;

            if ($i < 0) {
                $blockLength += $i;
                $i = 0;
            }

            $blockA = \substr($a, $i, $blockLength);
            $blockB = \substr($b, $i, $blockLength);

            $sum = $blockA - $blockB - $carry;

            if ($sum < 0) {
                $sum += $complement;
                $carry = 1;
            } else {
                $carry = 0;
            }

            $sum = (string) $sum;
            $sumLength = \strlen($sum);

            if ($sumLength < $blockLength) {
                $sum = \str_repeat('0', $blockLength - $sumLength) . $sum;
            }

            $result = $sum . $result;

            if ($i === 0) {
                break;
            }
        }

        // Carry cannot be 1 when the loop ends, as a > b
        assert($carry === 0);

        $result = \ltrim($result, '0');

        if ($invert) {
            $result = $this->neg($result);
        }

        return $result;
    }
948762
function B(iid, op, left, right, flags) {
        var bFlags = decodeBitPattern(flags, 3); // [isComputed, isOpAssign, isSwitchCaseComparison]
        var result, aret, skip = false;

        if (sandbox.analysis && sandbox.analysis.binaryPre) {
            aret = sandbox.analysis.binaryPre(iid, op, left, right, bFlags[1], bFlags[2], bFlags[0]);
            if (aret) {
                op = aret.op;
                left = aret.left;
                right = aret.right;
                skip = aret.skip;
            }
        }


        if (!skip) {
            switch (op) {
                case "+":
                    result = left + right;
                    break;
                case "-":
                    result = left - right;
                    break;
                case "*":
                    result = left * right;
                    break;
                case "/":
                    result = left / right;
                    break;
                case "%":
                    result = left % right;
                    break;
                case "<<":
                    result = left << right;
                    break;
                case ">>":
                    result = left >> right;
                    break;
                case ">>>":
                    result = left >>> right;
                    break;
                case "<":
                    result = left < right;
                    break;
                case ">":
                    result = left > right;
                    break;
                case "<=":
                    result = left <= right;
                    break;
                case ">=":
                    result = left >= right;
                    break;
                case "==":
                    result = left == right;
                    break;
                case "!=":
                    result = left != right;
                    break;
                case "===":
                    result = left === right;
                    break;
                case "!==":
                    result = left !== right;
                    break;
                case "&":
                    result = left & right;
                    break;
                case "|":
                    result = left | right;
                    break;
                case "^":
                    result = left ^ right;
                    break;
                case "delete":
                    result = delete left[right];
                    break;
                case "instanceof":
                    result = left instanceof right;
                    break;
                case "in":
                    result = left in right;
                    break;
                default:
                    throw new Error(op + " at " + iid + " not found");
                    break;
            }
        }

        if (sandbox.analysis && sandbox.analysis.binary) {
            aret = sandbox.analysis.binary(iid, op, left, right, result, bFlags[1], bFlags[2], bFlags[0]);
            if (aret) {
                result = aret.result;
            }
        }
        return (lastComputedValue = result);
    }
206651
function (a, shift, carry, out) {
    var i, last2=0, shift2;
    if (out === undefined) { out = []; }

    for (; shift >= 32; shift -= 32) {
      out.push(carry);
      carry = 0;
    }
    if (shift === 0) {
      return out.concat(a);
    }

    for (i=0; i<a.length; i++) {
      out.push(carry | a[i]>>>shift);
      carry = a[i] << (32-shift);
    }
    last2 = a.length ? a[a.length-1] : 0;
    shift2 = sjcl.bitArray.getPartial(last2);
    out.push(sjcl.bitArray.partial(shift+shift2 & 31, (shift + shift2 > 32) ? carry : out.pop(),1));
    return out;
  }
217104
private Node tryFoldShift(Node n, Node left, Node right) {
    if (left.isNumber() &&
        right.isNumber()) {

      double result;
      double lval = left.getDouble();
      double rval = right.getDouble();

      // only the lower 5 bits are used when shifting, so don't do anything
      // if the shift amount is outside [0,32)
      if (!(rval >= 0 && rval < 32)) {
        return n;
      }

      int rvalInt = (int) rval;
      if (rvalInt != rval) {
        report(FRACTIONAL_BITWISE_OPERAND, right);
        return n;
      }

      if (Math.floor(lval) != lval) {
        report(FRACTIONAL_BITWISE_OPERAND, left);
        return n;
      }

      int bits = jsConvertDoubleToBits(lval);

      switch (n.getToken()) {
        case LSH:
          result = bits << rvalInt;
          break;
        case RSH:
          result = bits >> rvalInt;
          break;
        case URSH:
          // JavaScript always treats the result of >>> as unsigned.
          // We must force Java to do the same here.
          result = 0xffffffffL & (bits >>> rvalInt);
          break;
        default:
          throw new AssertionError("Unknown shift operator: " + n.getToken());
      }

      Node newNumber = IR.number(result);
      reportChangeToEnclosingScope(n);
      n.replaceWith(newNumber);

      return newNumber;
    }

    return n;
  }
717276
public function computeWithoutBcMath(DecimalNumber $a, DecimalNumber $b)
    {
        if ($a->isNegative()) {
            if ($b->isNegative()) {
                // if both numbers are negative,
                // we can just add them as positive numbers and then invert the sign
                // f(x, y) = -(|x| + |y|)
                // eg. f(-1, -2) = -(|-1| + |-2|) = -3
                // eg. f(-2, -1) = -(|-2| + |-1|) = -3
                return $this
                    ->computeWithoutBcMath($a->toPositive(), $b->toPositive())
                    ->invert();
            }
            // if the number is negative and the addend positive,
            // perform an inverse subtraction by inverting the terms
            // f(x, y) = y - |x|
            // eg. f(-2, 1) = 1 - |-2| = -1
            // eg. f(-1, 2) = 2 - |-1| = 1
            // eg. f(-1, 1) = 1 - |-1| = 0
            return $b->minus(
                $a->toPositive()
            );
        }

        if ($b->isNegative()) {
            // if the number is positive and the addend is negative
            // perform subtraction instead: 2 - 1
            // f(x, y) = x - |y|
            // f(2, -1) = 2 - |-1| = 1
            // f(1, -2) = 1 - |-2| = -1
            // f(1, -1) = 1 - |-1| = 0
            return $a->minus(
                $b->toPositive()
            );
        }

        // optimization: 0 + x = x
        if ('0' === (string) $a) {
            return $b;
        }

        // optimization: x + 0 = x
        if ('0' === (string) $b) {
            return $a;
        }

        // pad coefficients with leading/trailing zeroes
        list($coeff1, $coeff2) = $this->normalizeCoefficients($a, $b);

        // compute the coefficient sum
        $sum = $this->addStrings($coeff1, $coeff2);

        // both signs are equal, so we can use either
        $sign = $a->getSign();

        // keep the bigger exponent
        $exponent = max($a->getExponent(), $b->getExponent());

        return new DecimalNumber($sign . $sum, $exponent);
    }
387760
private static int get16(byte[] b, int off) {
        return Byte.toUnsignedInt(b[off]) | ( Byte.toUnsignedInt(b[off+1]) << 8);
    }
451057
public static void writeInt(byte[] b, int offset, int value) {
    b[offset++] = (byte) (value >>> 24);
    b[offset++] = (byte) (value >>> 16);
    b[offset++] = (byte) (value >>> 8);
    b[offset] = (byte)value;
  }
435989
public Bits bitwiseXor(final Bits right) {
    final int lengthDifference = this.bitLength - right.bitLength;
    if (lengthDifference < 0) {
      return this.concatenate(
        new Bits(0l, -lengthDifference)).bitwiseXor(right);
    }
    if (lengthDifference > 0) {
      return this.bitwiseXor(right
        .concatenate(new Bits(0l, lengthDifference)));
    }
    final Bits returnValue = new Bits(
      new byte[this.bytes.length],
      this.bitLength);
    for (int i = 0; i < this.bytes.length; i++) {
      returnValue.bytes[i] = this.bytes[i];
    }
    for (int i = 0; i < right.bytes.length; i++) {
      returnValue.bytes[i] ^= right.bytes[i];
    }
    return returnValue;
  }
47198
public static int buff2int(byte[] bs, int offset) {
        return ((bs[offset] >= 0 ? bs[offset] : 256 + bs[offset]) << 24)
                | ((bs[offset + 1] >= 0 ? bs[offset + 1] : 256 + bs[offset + 1]) << 16)
                | ((bs[offset + 2] >= 0 ? bs[offset + 2] : 256 + bs[offset + 2]) << 8)
                | (bs[offset + 3] >= 0 ? bs[offset + 3] : 256 + bs[offset + 3]);
    }
782460
public static int positiveRightShift(int key, int shift) {
        int single = 0x3FF >> shift;
        int shiftMask = (single << 22) | (single << 11) | single;
        return shiftMask & (key >> shift);
    }
925051
@SuppressWarnings("deprecation")
    private static int unsignedShortBE(ByteBuf buffer, int offset) {
        return buffer.order() == ByteOrder.BIG_ENDIAN ?
                buffer.getUnsignedShort(offset) : buffer.getUnsignedShortLE(offset);
    }
1237800
function bnpFromRadix(s, b)
{
  this.fromInt(0);
  if (b == null) b = 10;
  var cs = this.chunkSize(b);
  var d = Math.pow(b, cs),
    mi = false,
    j = 0,
    w = 0;
  for (var i = 0; i < s.length; ++i)
  {
    var x = intAt(s, i);
    if (x < 0)
    {
      if (s.charAt(i) == "-" && this.signum() == 0) mi = true;
      continue;
    }
    w = b * w + x;
    if (++j >= cs)
    {
      this.dMultiply(d);
      this.dAddOffset(w, 0);
      j = 0;
      w = 0;
    }
  }
  if (j > 0)
  {
    this.dMultiply(Math.pow(b, j));
    this.dAddOffset(w, 0);
  }
  if (mi) Int128.ZERO.subTo(this, this);
}
739169
function _lshift($shift)
    {
        if ($shift == 0) {
            return;
        }

        $num_digits = (int) ($shift / self::$base);
        $shift %= self::$base;
        $shift = 1 << $shift;

        $carry = 0;

        for ($i = 0; $i < count($this->value); ++$i) {
            $temp = $this->value[$i] * $shift + $carry;
            $carry = self::$base === 26 ? intval($temp / 0x4000000) : ($temp >> 31);
            $this->value[$i] = (int) ($temp - $carry * self::$baseFull);
        }

        if ($carry) {
            $this->value[count($this->value)] = $carry;
        }

        while ($num_digits--) {
            array_unshift($this->value, 0);
        }
    }