/** * Performs long multiplication on two BigIntegers * * Modeled after 'multiply' in MutableBigInteger.java. * * @param Math_BigInteger $x * @return Math_BigInteger * @access private */ function _multiply($x) { $this_length = count($this->value); $x_length = count($x->value); if (!$this_length || !$x_length) { // a 0 is being multiplied return new Math_BigInteger(); } if ($this_length < $x_length) { return $x->_multiply($this); } $product = new Math_BigInteger(); $product->value = $this->_array_repeat(0, $this_length + $x_length); // the following for loop could be removed if the for loop following it // (the one with nested for loops) initially set $i to 0, but // doing so would also make the result in one set of unnecessary adds, // since on the outermost loops first pass, $product->value[$k] is going // to always be 0 $carry = 0; for ($j = 0; $j < $this_length; $j++) { // ie. $i = 0 $temp = $this->value[$j] * $x->value[0] + $carry; // $product->value[$k] == 0 $carry = floor($temp / 0x4000000); $product->value[$j] = $temp - 0x4000000 * $carry; } $product->value[$j] = $carry; // the above for loop is what the previous comment was talking about. the // following for loop is the "one with nested for loops" for ($i = 1; $i < $x_length; $i++) { $carry = 0; for ($j = 0, $k = $i; $j < $this_length; $j++, $k++) { $temp = $product->value[$k] + $this->value[$j] * $x->value[$i] + $carry; $carry = floor($temp / 0x4000000); $product->value[$k] = $temp - 0x4000000 * $carry; } $product->value[$k] = $carry; } $product->is_negative = $this->is_negative != $x->is_negative; return $this->_normalize($product); }