From 7cf300984cfb4e83029ada4c9a7ce239f1d3dc8c Mon Sep 17 00:00:00 2001 From: danogentili Date: Sun, 31 Jul 2016 22:15:48 +0200 Subject: [PATCH 1/3] Added root, pow, max, min, loopforeach functions and tests. --- phpseclib/Math/BigInteger.php | 237 ++++++++++++++++++++++++ tests/Unit/Math/BigInteger/TestCase.php | 101 ++++++++++ 2 files changed, 338 insertions(+) diff --git a/phpseclib/Math/BigInteger.php b/phpseclib/Math/BigInteger.php index 66fb48e4..b4513b6e 100644 --- a/phpseclib/Math/BigInteger.php +++ b/phpseclib/Math/BigInteger.php @@ -3674,4 +3674,241 @@ class BigInteger // self::$base === 31 return ($x - ($x % $y)) / $y; } + + /** + * Calculates the nth root of a biginteger. + * + * Returns the nth root of a positive biginteger, where n defaults to 2 + * + * Here's an example: + * + * root(); + * + * echo $root->toString(); // outputs 25 + * ?> + * + * + * @param \phpseclib\Math\BigInteger $n + * @access public + * @return \phpseclib\Math\BigInteger + * + * @internal This function is based off of {@link http://mathforum.org/library/drmath/view/52605.html this page} and {@link http://stackoverflow.com/questions/11242920/calculating-nth-root-with-bcmath-in-php this stackoverflow question}. + */ + function root($n = null) + { + $one = new static(1); + $two = new static(2); + if ($n === null) { + $n = $two; + } + if ($n->compare($one) == -1) { + return new static(0); + } // we want positive exponents + if ($this->compare($one) == -1) { + return new static(0); + } // we want positive numbers + if ($this->compare($two) == -1) { + return $one; + } // n-th root of 1 or 2 is 1 + $root = new static(); + switch (MATH_BIGINTEGER_MODE) { + case self::MODE_BCMATH: + // g is our guess number + $g = 2; + // while (g^n < num) g=g*2 + while (bccomp(bcpow($g, $n->value), $this->value) == -1) { + $g = bcmul($g, '2'); + } + // if (g^n==num) num is a power of 2, we're lucky, end of job + if (bccomp(bcpow($g, $n->value), $this->value) == 0) { + $root->value = $g; + break; + } + + // if we're here num wasn't a power of 2 :( + $og = $g; // og means original guess and here is our upper bound + $g = bcdiv($g, '2'); // g is set to be our lower bound + $step = bcdiv(bcsub($og, $g), '2'); // step is the half of upper bound - lower bound + $g = bcadd($g, $step); // we start at lower bound + step , basically in the middle of our interval + + // while step!=1 + + while (bccomp($step, '1') == 1) { + $guess = bcpow($g, $n); + $step = bcdiv($step, '2'); + $comp = bccomp($guess, $this->value); // compare our guess with real number + if ($comp == -1) { // if guess is lower we add the new step + $g = bcadd($g, $step); + } elseif ($comp == 1) { // if guess is higher we sub the new step + $g = bcsub($g, $step); + } else { // if guess is exactly the num we're done, we return the value + $root->value = $g; + break; + } + } + + // whatever happened, g is the closest guess we can make so return it + $root->value = $g; + break; + case self::MODE_GMP: + if (function_exists('gmp_root')) { + $root->value = gmp_root($this->value, gmp_intval($n->value)); + break; + } + default: + // g is our guess number + $g = $two; + // while (g^n < num) g=g*2 + while ($g->pow($n)->compare($this) == -1) { + $g = $g->multiply($two); + } + // if (g^n==num) num is a power of 2, we're lucky, end of job + // == 0 bccomp(bcpow($g,$n), $n->value)==0 + if ($g->pow($n)->equals($this)) { + $root = $g; + break; + } + + // if we're here num wasn't a power of 2 :( + $og = $g; // og means original guess and here is our upper bound + $g = $g->divide($two)[0]; // g is set to be our lower bound + $step = $og->subtract($g)->divide($two)[0]; // step is the half of upper bound - lower bound + $g = $g->add($step); // we start at lower bound + step , basically in the middle of our interval + + // while step!=1 + + while ($step->compare($one) == 1) { + $guess = $g->pow($n); + $step = $step->divide($two)[0]; + $comp = $guess->compare($this); // compare our guess with real number + if ($comp == -1) { // if guess is lower we add the new step + $g = $g->add($step); + } elseif ($comp == 1) { // if guess is higher we sub the new step + $g = $g->subtract($step); + } else { // if guess is exactly the num we're done, we return the value + $root = $g; + break; + } + } + + // whatever happened, g is the closest guess we can make so return it + $root = $g; + break; + } + + return $this->_normalize($root); + } + + /** + * Performs exponentiation. + * + * + * @param \phpseclib\Math\BigInteger $n + * @access public + * @return \phpseclib\Math\BigInteger + */ + function pow($n) + { + $zero = new static(0); + if ($n->compare($zero) == 0) { + return new static(1); + } // n^0 = 1 + + $res = new static(); + switch (MATH_BIGINTEGER_MODE) { + case self::MODE_GMP: + $res->value = gmp_pow($this->value, gmp_intval($n->value)); + + return $this->_normalize($res); + case self::MODE_BCMATH: + $res->value = bcpow($this->value, $n->value); + + return $this->_normalize($res); + default: + $one = new static(1); + $res = $this; + while (!$n->equals($one)) { + $res = $res->multiply($this); + $n = $n->subtract($one); + } + + return $res; + break; + } + } + + /** + * Return the minimum BigInteger between two BigIntegers. + * + * + * @param \phpseclib\Math\BigInteger $a + * @param \phpseclib\Math\BigInteger $b + * @access public + * + * + * @return \phpseclib\Math\BigInteger + */ + function min($b) + { + if ($this->compare($b) == '1') { + return $b; + } + + return $this; + } + + /** + * Return the maximum BigInteger between two BigIntegers. + * + * + * @param \phpseclib\Math\BigInteger $b + * @access public + * + * @return \phpseclib\Math\BigInteger + */ + function max($b) + { + if ($this->compare($b) == '1') { + return $this; + } + + return $b; + } + + /** + * Execute a function n times, where n is the current BigInteger. + * The passed function must accept a paremeter that will be set to the the current number + * (that number will range from zero to BigInteger - 1 if the BigInteger is positive, and from BigInteger - 1 to zero if the BigInteger is negative). + * You can also set it to accept an optional parameter, that will be equal to the optional $userdata parameter. + * + * @access public + * @param callable $function + * @param &$userdata + * + * @return \phpseclib\Math\BigInteger + */ + function loopforeach(callable $function, &$userdata = null) + { + if ($this->compare(new static(0)) < 0) { // negative + $limit = new static(-PHP_INT_MAX - 1); + $one = new static(-1); + } else { // positive + $limit = new static(PHP_INT_MAX); + $one = new static(1); + } + if ($this->compare($limit) == -((int) $one->toString())) { + $oneint = (int) $one->toString(); + $thisint = (int) $this->toString(); + for ($loop = 0; $loop != $thisint; $loop += $oneint) { + $function($loop, $userdata); + } + } else { + for ($loop = new static(0); !$loop->equals($this); $loop = $loop->add($one)) { + $function((string) $loop, $userdata); + } + } + } } diff --git a/tests/Unit/Math/BigInteger/TestCase.php b/tests/Unit/Math/BigInteger/TestCase.php index 8226c0b5..37a7191e 100644 --- a/tests/Unit/Math/BigInteger/TestCase.php +++ b/tests/Unit/Math/BigInteger/TestCase.php @@ -380,4 +380,105 @@ abstract class Unit_Math_BigInteger_TestCase extends PhpseclibTestCase $n = $this->getInstance(2); $x->powMod($e, $n); } + public function testRoot() + { + $bigInteger = new \phpseclib\Math\BigInteger('64000000'); // (20^2)^3 + $three = new \phpseclib\Math\BigInteger('3'); + $bigInteger = $bigInteger->root(); + $this->assertSame('8000', (string) $bigInteger); + $bigInteger = $bigInteger->root($three); + $this->assertSame('20', (string) $bigInteger); + } + + public function testPow() + { + $bigInteger = new \phpseclib\Math\BigInteger('20'); + $two = new \phpseclib\Math\BigInteger('2'); + $three = new \phpseclib\Math\BigInteger('3'); + $bigInteger = $bigInteger->pow($two); + $this->assertSame('400', (string) $bigInteger); + $bigInteger = $bigInteger->pow($three); + $this->assertSame('64000000', (string) $bigInteger); // (20^2)^3 + } + + public function testMax() + { + $min = new \phpseclib\Math\BigInteger('20'); + $max = new \phpseclib\Math\BigInteger('20000'); + $this->assertSame((string) $max, (string) $min->max($max)); + $this->assertSame((string) $max, (string) $max->max($min)); + } + + public function testMin() + { + $min = new \phpseclib\Math\BigInteger('20'); + $max = new \phpseclib\Math\BigInteger('20000'); + $this->assertSame((string) $min, (string) $min->min($max)); + $this->assertSame((string) $min, (string) $max->min($min)); + } + + public function testLoopForeach() + { + $maxBigInteger = new \phpseclib\Math\BigInteger('34'); + $one = new \phpseclib\Math\BigInteger('1'); + $vars = []; + $maxBigInteger->loopforeach( + function ($i, &$vars) { + if ($i == 0) { + $vars['first'] = $i; + } else { + $vars['last'] = $i; + } + }, + $vars + ); + $this->assertSame(0, $vars['first']); + $this->assertSame(33, $vars['last']); + /* Nope, too slow + $maxBigInteger = new \phpseclib\Math\BigInteger(PHP_INT_MAX); + $maxBigInteger = $maxBigInteger->add($one); + $maxBigInteger->loopforeach( + function ($i, &$vars) { + if ($i == 0) { + $vars["first"] = $i; + } else { + $vars["last"] = $i; + } + }, + $vars + ); + $this->assertSame("0", $vars["first"]); + $this->assertSame((string)$maxBigInteger->subtract($one), $vars["last"]);*/ + + + $maxBigInteger = new \phpseclib\Math\BigInteger(-34); + $maxBigInteger->loopforeach( + function ($i, &$vars) { + if ($i == 0) { + $vars['first'] = $i; + } else { + $vars['last'] = $i; + } + }, + $vars + ); + $this->assertSame(0, $vars['first']); + $this->assertSame(-33, $vars['last']); + /* Nope, too slow + $maxBigInteger = new \phpseclib\Math\BigInteger(-PHP_INT_MAX - 1); + $maxBigInteger = $maxBigInteger->subtract($one); + + $maxBigInteger->loopforeach( + function ($i, &$vars) { + if ($i == 0) { + $vars["first"] = $i; + } else { + $vars["last"] = $i; + } + }, + $vars + ); + $this->assertSame("0", $vars["first"]); + $this->assertSame((string)$maxBigInteger->add($one), $vars["last"]);*/ + } } From 72d1bdf60be855df4a7e9cefdccd04f7a89355f4 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Wed, 7 Sep 2016 23:26:22 -0800 Subject: [PATCH 2/3] a few changes to danog's changes --- phpseclib/Math/BigInteger.php | 198 ++++++++++-------------- tests/Unit/Math/BigInteger/TestCase.php | 8 +- 2 files changed, 90 insertions(+), 116 deletions(-) diff --git a/phpseclib/Math/BigInteger.php b/phpseclib/Math/BigInteger.php index b4513b6e..abc6ef0c 100644 --- a/phpseclib/Math/BigInteger.php +++ b/phpseclib/Math/BigInteger.php @@ -3699,13 +3699,17 @@ class BigInteger */ function root($n = null) { - $one = new static(1); - $two = new static(2); + static $zero, $one, $two; + if (!isset($one)) { + $zero = new static(0); + $one = new static(1); + $two = new static(2); + } if ($n === null) { $n = $two; } if ($n->compare($one) == -1) { - return new static(0); + return $zero; } // we want positive exponents if ($this->compare($one) == -1) { return new static(0); @@ -3713,99 +3717,64 @@ class BigInteger if ($this->compare($two) == -1) { return $one; } // n-th root of 1 or 2 is 1 + $root = new static(); - switch (MATH_BIGINTEGER_MODE) { - case self::MODE_BCMATH: - // g is our guess number - $g = 2; - // while (g^n < num) g=g*2 - while (bccomp(bcpow($g, $n->value), $this->value) == -1) { - $g = bcmul($g, '2'); - } - // if (g^n==num) num is a power of 2, we're lucky, end of job - if (bccomp(bcpow($g, $n->value), $this->value) == 0) { - $root->value = $g; - break; - } - - // if we're here num wasn't a power of 2 :( - $og = $g; // og means original guess and here is our upper bound - $g = bcdiv($g, '2'); // g is set to be our lower bound - $step = bcdiv(bcsub($og, $g), '2'); // step is the half of upper bound - lower bound - $g = bcadd($g, $step); // we start at lower bound + step , basically in the middle of our interval - - // while step!=1 - - while (bccomp($step, '1') == 1) { - $guess = bcpow($g, $n); - $step = bcdiv($step, '2'); - $comp = bccomp($guess, $this->value); // compare our guess with real number - if ($comp == -1) { // if guess is lower we add the new step - $g = bcadd($g, $step); - } elseif ($comp == 1) { // if guess is higher we sub the new step - $g = bcsub($g, $step); - } else { // if guess is exactly the num we're done, we return the value - $root->value = $g; - break; - } - } - - // whatever happened, g is the closest guess we can make so return it - $root->value = $g; - break; - case self::MODE_GMP: - if (function_exists('gmp_root')) { - $root->value = gmp_root($this->value, gmp_intval($n->value)); - break; - } - default: - // g is our guess number - $g = $two; - // while (g^n < num) g=g*2 - while ($g->pow($n)->compare($this) == -1) { - $g = $g->multiply($two); - } - // if (g^n==num) num is a power of 2, we're lucky, end of job - // == 0 bccomp(bcpow($g,$n), $n->value)==0 - if ($g->pow($n)->equals($this)) { - $root = $g; - break; - } - - // if we're here num wasn't a power of 2 :( - $og = $g; // og means original guess and here is our upper bound - $g = $g->divide($two)[0]; // g is set to be our lower bound - $step = $og->subtract($g)->divide($two)[0]; // step is the half of upper bound - lower bound - $g = $g->add($step); // we start at lower bound + step , basically in the middle of our interval - - // while step!=1 - - while ($step->compare($one) == 1) { - $guess = $g->pow($n); - $step = $step->divide($two)[0]; - $comp = $guess->compare($this); // compare our guess with real number - if ($comp == -1) { // if guess is lower we add the new step - $g = $g->add($step); - } elseif ($comp == 1) { // if guess is higher we sub the new step - $g = $g->subtract($step); - } else { // if guess is exactly the num we're done, we return the value - $root = $g; - break; - } - } - - // whatever happened, g is the closest guess we can make so return it - $root = $g; - break; + if (MATH_BIGINTEGER_MODE == self::MODE_GMP && function_exists('gmp_root')) { + $root->value = gmp_root($this->value, gmp_intval($n->value)); + return $this->_normalize($root); } + // g is our guess number + $g = $two; + // while (g^n < num) g=g*2 + while ($g->pow($n)->compare($this) == -1) { + $g = $g->multiply($two); + } + // if (g^n==num) num is a power of 2, we're lucky, end of job + // == 0 bccomp(bcpow($g,$n), $n->value)==0 + if ($g->pow($n)->equals($this)) { + $root = $g; + return $this->_normalize($root); + } + + // if we're here num wasn't a power of 2 :( + $og = $g; // og means original guess and here is our upper bound + $g = $g->divide($two)[0]; // g is set to be our lower bound + $step = $og->subtract($g)->divide($two)[0]; // step is the half of upper bound - lower bound + $g = $g->add($step); // we start at lower bound + step , basically in the middle of our interval + + // while step>1 + + while ($step->compare($one) == 1) { + $guess = $g->pow($n); + $step = $step->divide($two)[0]; + $comp = $guess->compare($this); // compare our guess with real number + switch ($comp) { + case -1: // if guess is lower we add the new step + $g = $g->add($step); + break; + case 1: // if guess is higher we sub the new step + $g = $g->subtract($step); + break; + case 0: // if guess is exactly the num we're done, we return the value + $root = $g; + break 2; + } + } + + if ($comp == 1) { + $g = $g->subtract($step); + } + + // whatever happened, g is the closest guess we can make so return it + $root = $g; + return $this->_normalize($root); } /** * Performs exponentiation. * - * * @param \phpseclib\Math\BigInteger $n * @access public * @return \phpseclib\Math\BigInteger @@ -3836,73 +3805,78 @@ class BigInteger } return $res; - break; } } /** - * Return the minimum BigInteger between two BigIntegers. + * Return the minimum BigInteger between an arbitrary number of BigIntegers. * - * - * @param \phpseclib\Math\BigInteger $a - * @param \phpseclib\Math\BigInteger $b + * @param \phpseclib\Math\BigInteger ...$param * @access public - * - * * @return \phpseclib\Math\BigInteger */ - function min($b) + static function min() { - if ($this->compare($b) == '1') { - return $b; + $args = func_get_args(); + if (count($args) == 1) { + return $args[0]; } - - return $this; + $min = $args[0]; + for ($i = 1; $i < count($args); $i++) { + $min = $min->compare($args[$i]) > 0 ? $args[$i] : $min; + } + return $min; } /** - * Return the maximum BigInteger between two BigIntegers. + * Return the maximum BigInteger between an arbitrary number of BigIntegers. * - * - * @param \phpseclib\Math\BigInteger $b + * @param \phpseclib\Math\BigInteger ...$param * @access public - * * @return \phpseclib\Math\BigInteger */ - function max($b) + static function max() { - if ($this->compare($b) == '1') { - return $this; + $args = func_get_args(); + if (count($args) == 1) { + return $args[0]; } - - return $b; + $max = $args[0]; + for ($i = 1; $i < count($args); $i++) { + $max = $max->compare($args[$i]) < 0 ? $args[$i] : $max; + } + return $max; } /** * Execute a function n times, where n is the current BigInteger. - * The passed function must accept a paremeter that will be set to the the current number + * The passed function must accept a parameter that will be set to the the current number * (that number will range from zero to BigInteger - 1 if the BigInteger is positive, and from BigInteger - 1 to zero if the BigInteger is negative). * You can also set it to accept an optional parameter, that will be equal to the optional $userdata parameter. * * @access public * @param callable $function * @param &$userdata - * * @return \phpseclib\Math\BigInteger */ function loopforeach(callable $function, &$userdata = null) { - if ($this->compare(new static(0)) < 0) { // negative + static $zero; + if (!isset($zero)) { + $zero = new static(0); + } + if ($this->compare($zero) < 0) { // negative $limit = new static(-PHP_INT_MAX - 1); $one = new static(-1); } else { // positive $limit = new static(PHP_INT_MAX); $one = new static(1); } + if ($this->compare($limit) == -((int) $one->toString())) { $oneint = (int) $one->toString(); $thisint = (int) $this->toString(); - for ($loop = 0; $loop != $thisint; $loop += $oneint) { + for ($loop = 0; $loop != $thisint; $loop+= $oneint) { $function($loop, $userdata); } } else { diff --git a/tests/Unit/Math/BigInteger/TestCase.php b/tests/Unit/Math/BigInteger/TestCase.php index 37a7191e..c4a51eac 100644 --- a/tests/Unit/Math/BigInteger/TestCase.php +++ b/tests/Unit/Math/BigInteger/TestCase.php @@ -405,16 +405,16 @@ abstract class Unit_Math_BigInteger_TestCase extends PhpseclibTestCase { $min = new \phpseclib\Math\BigInteger('20'); $max = new \phpseclib\Math\BigInteger('20000'); - $this->assertSame((string) $max, (string) $min->max($max)); - $this->assertSame((string) $max, (string) $max->max($min)); + $this->assertSame((string) $max, (string) \phpseclib\Math\BigInteger::max($min, $max)); + $this->assertSame((string) $max, (string) \phpseclib\Math\BigInteger::max($max, $min)); } public function testMin() { $min = new \phpseclib\Math\BigInteger('20'); $max = new \phpseclib\Math\BigInteger('20000'); - $this->assertSame((string) $min, (string) $min->min($max)); - $this->assertSame((string) $min, (string) $max->min($min)); + $this->assertSame((string) $min, (string) \phpseclib\Math\BigInteger::min($min, $max)); + $this->assertSame((string) $min, (string) \phpseclib\Math\BigInteger::min($max, $min)); } public function testLoopForeach() From 0ee24aa21843efa6165d36418dd7e4c3e96c8fe9 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Fri, 9 Sep 2016 20:59:54 -0800 Subject: [PATCH 3/3] BigInteger: rm loopforeach method --- phpseclib/Math/BigInteger.php | 38 --------------- tests/Unit/Math/BigInteger/TestCase.php | 65 ------------------------- 2 files changed, 103 deletions(-) diff --git a/phpseclib/Math/BigInteger.php b/phpseclib/Math/BigInteger.php index abc6ef0c..eea04934 100644 --- a/phpseclib/Math/BigInteger.php +++ b/phpseclib/Math/BigInteger.php @@ -3847,42 +3847,4 @@ class BigInteger } return $max; } - - /** - * Execute a function n times, where n is the current BigInteger. - * The passed function must accept a parameter that will be set to the the current number - * (that number will range from zero to BigInteger - 1 if the BigInteger is positive, and from BigInteger - 1 to zero if the BigInteger is negative). - * You can also set it to accept an optional parameter, that will be equal to the optional $userdata parameter. - * - * @access public - * @param callable $function - * @param &$userdata - * @return \phpseclib\Math\BigInteger - */ - function loopforeach(callable $function, &$userdata = null) - { - static $zero; - if (!isset($zero)) { - $zero = new static(0); - } - if ($this->compare($zero) < 0) { // negative - $limit = new static(-PHP_INT_MAX - 1); - $one = new static(-1); - } else { // positive - $limit = new static(PHP_INT_MAX); - $one = new static(1); - } - - if ($this->compare($limit) == -((int) $one->toString())) { - $oneint = (int) $one->toString(); - $thisint = (int) $this->toString(); - for ($loop = 0; $loop != $thisint; $loop+= $oneint) { - $function($loop, $userdata); - } - } else { - for ($loop = new static(0); !$loop->equals($this); $loop = $loop->add($one)) { - $function((string) $loop, $userdata); - } - } - } } diff --git a/tests/Unit/Math/BigInteger/TestCase.php b/tests/Unit/Math/BigInteger/TestCase.php index c4a51eac..26b6dd90 100644 --- a/tests/Unit/Math/BigInteger/TestCase.php +++ b/tests/Unit/Math/BigInteger/TestCase.php @@ -416,69 +416,4 @@ abstract class Unit_Math_BigInteger_TestCase extends PhpseclibTestCase $this->assertSame((string) $min, (string) \phpseclib\Math\BigInteger::min($min, $max)); $this->assertSame((string) $min, (string) \phpseclib\Math\BigInteger::min($max, $min)); } - - public function testLoopForeach() - { - $maxBigInteger = new \phpseclib\Math\BigInteger('34'); - $one = new \phpseclib\Math\BigInteger('1'); - $vars = []; - $maxBigInteger->loopforeach( - function ($i, &$vars) { - if ($i == 0) { - $vars['first'] = $i; - } else { - $vars['last'] = $i; - } - }, - $vars - ); - $this->assertSame(0, $vars['first']); - $this->assertSame(33, $vars['last']); - /* Nope, too slow - $maxBigInteger = new \phpseclib\Math\BigInteger(PHP_INT_MAX); - $maxBigInteger = $maxBigInteger->add($one); - $maxBigInteger->loopforeach( - function ($i, &$vars) { - if ($i == 0) { - $vars["first"] = $i; - } else { - $vars["last"] = $i; - } - }, - $vars - ); - $this->assertSame("0", $vars["first"]); - $this->assertSame((string)$maxBigInteger->subtract($one), $vars["last"]);*/ - - - $maxBigInteger = new \phpseclib\Math\BigInteger(-34); - $maxBigInteger->loopforeach( - function ($i, &$vars) { - if ($i == 0) { - $vars['first'] = $i; - } else { - $vars['last'] = $i; - } - }, - $vars - ); - $this->assertSame(0, $vars['first']); - $this->assertSame(-33, $vars['last']); - /* Nope, too slow - $maxBigInteger = new \phpseclib\Math\BigInteger(-PHP_INT_MAX - 1); - $maxBigInteger = $maxBigInteger->subtract($one); - - $maxBigInteger->loopforeach( - function ($i, &$vars) { - if ($i == 0) { - $vars["first"] = $i; - } else { - $vars["last"] = $i; - } - }, - $vars - ); - $this->assertSame("0", $vars["first"]); - $this->assertSame((string)$maxBigInteger->add($one), $vars["last"]);*/ - } }