toSameLength($a, $b); return $a < $b ? -1 : ($a > $b ? 1 : 0); } /** * Add 1 to a non-negative integer represented in binary form. * * @param string $value * * @return string */ public function increment($value) { $lastZeroIndex = strrpos($value, '0'); if ($lastZeroIndex === false) { return '1' . str_repeat('0', strlen($value)); } return ltrim(substr($value, 0, $lastZeroIndex), '0') . '1' . str_repeat('0', strlen($value) - $lastZeroIndex - 1); } /** * Calculate the bitwise AND of two non-negative integers represented in binary form. * * @param string $operand1 * @param string $operand2 * * @return string */ public function andX($operand1, $operand2) { $operand1 = $this->reduce($operand1); $operand2 = $this->reduce($operand2); $numBits = min(strlen($operand1), strlen($operand2)); $operand1 = substr(str_pad($operand1, $numBits, '0', STR_PAD_LEFT), -$numBits); $operand2 = substr(str_pad($operand2, $numBits, '0', STR_PAD_LEFT), -$numBits); $result = ''; for ($index = 0; $index < $numBits; $index++) { $result .= $operand1[$index] === '1' && $operand2[$index] === '1' ? '1' : '0'; } return $this->reduce($result); } /** * Calculate the bitwise OR of two non-negative integers represented in binary form. * * @param string $operand1 * @param string $operand2 * * @return string */ public function orX($operand1, $operand2) { list($operand1, $operand2, $numBits) = $this->toSameLength($operand1, $operand2); $result = ''; for ($index = 0; $index < $numBits; $index++) { $result .= $operand1[$index] === '1' || $operand2[$index] === '1' ? '1' : '0'; } return $result; } /** * Zero-padding of two non-negative integers represented in binary form, so that they have the same length. * * @param string $num1 * @param string $num2 * * @return string[],int[] The first array element is $num1 (padded), the first array element is $num2 (padded), the third array element is the number of bits */ private function toSameLength($num1, $num2) { $num1 = $this->reduce($num1); $num2 = $this->reduce($num2); $numBits = max(strlen($num1), strlen($num2)); return array( str_pad($num1, $numBits, '0', STR_PAD_LEFT), str_pad($num2, $numBits, '0', STR_PAD_LEFT), $numBits, ); } }