BigInteger: make the bitwise methods better handle negative numbers

This commit is contained in:
terrafrost 2019-04-10 06:53:00 -05:00
parent 31c10f39e5
commit 75f51fc8cc
4 changed files with 62 additions and 91 deletions

View File

@ -368,15 +368,7 @@ class BCMath extends Engine
*/
public function bitwise_and(BCMath $x)
{
$left = $this->toBytes();
$right = $x->toBytes();
$length = max(strlen($left), strlen($right));
$left = str_pad($left, $length, chr(0), STR_PAD_LEFT);
$right = str_pad($right, $length, chr(0), STR_PAD_LEFT);
return $this->normalize(new static($left & $right, 256));
return $this->bitwiseAndHelper($x);
}
/**
@ -387,15 +379,7 @@ class BCMath extends Engine
*/
public function bitwise_or(BCMath $x)
{
$left = $this->toBytes();
$right = $x->toBytes();
$length = max(strlen($left), strlen($right));
$left = str_pad($left, $length, chr(0), STR_PAD_LEFT);
$right = str_pad($right, $length, chr(0), STR_PAD_LEFT);
return $this->normalize(new static($left | $right, 256));
return $this->bitwiseXorHelper($x);
}
/**
@ -406,15 +390,7 @@ class BCMath extends Engine
*/
public function bitwise_xor(BCMath $x)
{
$left = $this->toBytes();
$right = $x->toBytes();
$length = max(strlen($left), strlen($right));
$left = str_pad($left, $length, chr(0), STR_PAD_LEFT);
$right = str_pad($right, $length, chr(0), STR_PAD_LEFT);
return $this->normalize(new static($left ^ $right, 256));
return $this->bitwiseXorHelper($x);
}
/**

View File

@ -1156,4 +1156,61 @@ abstract class Engine implements \Serializable
return array_reverse($vals);
}
}
/**
* Logical And
*
* @param Engine $x
* @return Engine
*/
protected function bitwiseAndHelper(Engine $x)
{
$left = $this->toBytes(true);
$right = $x->toBytes(true);
$length = max(strlen($left), strlen($right));
$left = str_pad($left, $length, chr(0), STR_PAD_LEFT);
$right = str_pad($right, $length, chr(0), STR_PAD_LEFT);
return $this->normalize(new static($left & $right, -256));
}
/**
* Logical Or
*
* @param Engine $x
* @return Engine
*/
protected function bitwiseOrHelper(Engine $x)
{
$left = $this->toBytes(true);
$right = $x->toBytes(true);
$length = max(strlen($left), strlen($right));
$left = str_pad($left, $length, chr(0), STR_PAD_LEFT);
$right = str_pad($right, $length, chr(0), STR_PAD_LEFT);
return $this->normalize(new static($left | $right, -256));
}
/**
* Logical Exclusive Or
*
* @param Engine $x
* @return Engine
*/
protected function bitwiseXorHelper(Engine $x)
{
$left = $this->toBytes(true);
$right = $x->toBytes(true);
$length = max(strlen($left), strlen($right));
$left = str_pad($left, $length, chr(0), STR_PAD_LEFT);
$right = str_pad($right, $length, chr(0), STR_PAD_LEFT);
return $this->normalize(new static($left ^ $right, -256));
}
}

View File

@ -415,7 +415,7 @@ class GMP extends Engine
public function bitwise_xor(GMP $x)
{
$temp = new self();
$temp->value = gmp_abs($this->value) ^ gmp_abs($x->value);
$temp->value = $this->value ^ $x->value;
return $this->normalize($temp);
}

View File

@ -801,68 +801,6 @@ abstract class PHP extends Engine
return $temp;
}
/**
* Logical And
*
* @param PHP $x
* @return PHP
*/
protected function bitwiseAndHelper(PHP $x)
{
$result = clone $this;
$length = min(count($x->value), count($this->value));
$result->value = array_slice($result->value, 0, $length);
for ($i = 0; $i < $length; ++$i) {
$result->value[$i]&= $x->value[$i];
}
return $this->normalize($result);
}
/**
* Logical Or
*
* @param PHP $x
* @return PHP
*/
protected function bitwiseOrHelper(PHP $x)
{
$length = max(count($this->value), count($x->value));
$result = clone $this;
$result->value = array_pad($result->value, $length, 0);
$x->value = array_pad($x->value, $length, 0);
for ($i = 0; $i < $length; ++$i) {
$result->value[$i]|= $x->value[$i];
}
return $this->normalize($result);
}
/**
* Logical Exclusive Or
*
* @param PHP $x
* @return PHP
*/
protected function bitwiseXorHelper(PHP $x)
{
$length = max(count($this->value), count($x->value));
$result = clone $this;
$result->is_negative = false;
$result->value = array_pad($result->value, $length, 0);
$x->value = array_pad($x->value, $length, 0);
for ($i = 0; $i < $length; ++$i) {
$result->value[$i]^= $x->value[$i];
}
return $this->normalize($result);
}
/**
* Trim
*