Adds two arbitrary precision numbers.

@param  string $a  The first number.
@param  string $b  The second number.
@return string
197658
public function add($a, $b)
    {
        return bcadd($this->bcNormalize($a), $this->bcNormalize($b));
    }
1327552
public static function unsignedRightShift(int $a, int $b) : int
    {
        return (
            $a >= 0
            ? $a >> $b
            : (($a & 0x7fffffff) >> $b) | (0x40000000 >> ($b - 1))
        );
    }
93938
public static function equal( $a, $b, int $precision = 0 ): bool {
    return self::write( $a, $precision ) === self::write( $b, $precision );
  }
852627
public function coprime($a, $b)
    {
        list($a, $b) = array($this->bcNormalize($a), $this->bcNormalize($b));

        try {

            while ($this->coCompare($a, $b)) {
                list($a, $b) = $this->coSwitch($a, $b);
            }

        } catch (\Exception $e) {
            throw $e;
        }

        return (bccomp($a, '1') == 0) ? true : false;
    }
78486
public function power($a, $b)
    {
        return bcpow($this->bcNormalize($a), $this->bcNormalize($b));
    }
1202898
protected function compare(string $a, string $b): int
    {
        global $sortOrder;

        $aIndex = array_search($a, $sortOrder);
        $bIndex = array_search($b, $sortOrder);
        if ($aIndex === false) {
            return -1;
        }

        if ($bIndex === false) {
            return 1;
        }

        return $aIndex - $bIndex;
    }
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);
    }
295002
private function normalizeCoefficients(DecimalNumber $a, DecimalNumber $b)
    {
        $exp1 = $a->getExponent();
        $exp2 = $b->getExponent();

        $coeff1 = $a->getCoefficient();
        $coeff2 = $b->getCoefficient();

        // add trailing zeroes if needed
        if ($exp1 > $exp2) {
            $coeff2 = str_pad($coeff2, strlen($coeff2) + $exp1 - $exp2, '0', STR_PAD_RIGHT);
        } elseif ($exp1 < $exp2) {
            $coeff1 = str_pad($coeff1, strlen($coeff1) + $exp2 - $exp1, '0', STR_PAD_RIGHT);
        }

        $len1 = strlen($coeff1);
        $len2 = strlen($coeff2);

        // add leading zeroes if needed
        if ($len1 > $len2) {
            $coeff2 = str_pad($coeff2, $len1, '0', STR_PAD_LEFT);
        } elseif ($len1 < $len2) {
            $coeff1 = str_pad($coeff1, $len2, '0', STR_PAD_LEFT);
        }

        return [$coeff1, $coeff2];
    }
896782
public static function merge($a, $b)
    {
        $acon = static::parse($a);
        $bcon = static::parse($b);

        if ($acon instanceof EmptyConstraint) {
            return $b;
        } elseif ($bcon instanceof EmptyConstraint) {
            return $a;
        } elseif ($acon->matches($bcon) || $bcon->matches($acon)) {
            return strlen($a) > strlen($b) ? $b : $a;
        } else {
            return $a . ' ' . $b;
        }
    }
1358544
private function doMul(string $a, string $b) : string
    {
        $x = \strlen($a);
        $y = \strlen($b);

        $maxDigits = \intdiv($this->maxDigits, 2);
        $complement = 10 ** $maxDigits;

        $result = '0';

        for ($i = $x - $maxDigits;; $i -= $maxDigits) {
            $blockALength = $maxDigits;

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

            $blockA = (int) \substr($a, $i, $blockALength);

            $line = '';
            $carry = 0;

            for ($j = $y - $maxDigits;; $j -= $maxDigits) {
                $blockBLength = $maxDigits;

                if ($j < 0) {
                    $blockBLength += $j;
                    $j = 0;
                }

                $blockB = (int) \substr($b, $j, $blockBLength);

                $mul = $blockA * $blockB + $carry;
                $value = $mul % $complement;
                $carry = ($mul - $value) / $complement;

                $value = (string) $value;
                $value = \str_pad($value, $maxDigits, '0', STR_PAD_LEFT);

                $line = $value . $line;

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

            if ($carry !== 0) {
                $line = $carry . $line;
            }

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

            if ($line !== '') {
                $line .= \str_repeat('0', $x - $blockALength - $i);
                $result = $this->add($result, $line);
            }

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

        return $result;
    }
1002492
public static double mod(double a, double b) {
		int n = (int)(a/b);
		
		a -= n*b;
		if (a < 0)
			return a + b;
		return a;
	}
1079286
public function distance(array $a, array $b): float
    {
        if (count($a) !== count($b)) {
            throw InvalidArgumentException::arraySizeNotMatch();
        }

        $distance = 0;

        foreach ($a as $i => $val) {
            $distance += ($val - $b[$i]) ** 2;
        }

        return sqrt((float) $distance);
    }
804453
public function floatSub(NI $a, NI $b)
    {
        list($a, $b) = $this->checkFloatTypes($a, $b);
        return new FloatType($a() - $b());
    }
405075
public static function Multiply( $a, $b )
	{
		if ( ! is_numeric( $b ) )
			throw new \InvalidArgumentException( "Division denominator is not a number" );

		if ( is_nan( $b ) )
	        throw XPath2Exception::withErrorCode( "FOCA0005", Resources::FOCA0005 );

        if ( $b == INF || $b == -INF )
        	throw XPath2Exception::withErrorCode( "FODT0002", Resources::FODT0002 );

		if ( ! $a instanceof DayTimeDurationValue )
	        throw new ArgumentException("$a");

		// Create a new interval with the multiplied days. ->days is created by the ->diff function to hold the total days.
		$multipliedSeconds = $a->getTotalSeconds()->Mul( $b )->getRound(3);
		$multipliedInterval = new \DateInterval("P0D");
		$multipliedInterval->s = $multipliedSeconds->getIntegerPart();
		$microseconds = $multipliedSeconds->getDecimalPart() + 0;
		$sign = $multipliedSeconds->getIsNegative();

		// Finally convert $multipliedInterval into a normalized interval
		$dt = new \DateTimeImmutable();
		$tz = new \DateTimeZone("Z");
		$dt = $dt->setTimezone( $tz );
		$diff = $dt->add( $multipliedInterval )->diff( $dt );
		$diff->hasValue = $multipliedSeconds->getValue() != 0;
		$diff->invert = ! $diff->invert;
		$diff->microseconds = $microseconds;
		// $diff->daysOnly = false;

	    return new DayTimeDurationValue( $diff );
	}
313772
final public function cmp(string $a, string $b) : int
    {
        $this->init($a, $b, $aDig, $bDig, $aNeg, $bNeg);

        if ($aNeg && ! $bNeg) {
            return -1;
        }

        if ($bNeg && ! $aNeg) {
            return 1;
        }

        $aLen = \strlen($aDig);
        $bLen = \strlen($bDig);

        if ($aLen < $bLen) {
            $result = -1;
        } elseif ($aLen > $bLen) {
            $result = 1;
        } else {
            $result = $aDig <=> $bDig;
        }

        return $aNeg ? -$result : $result;
    }
1207793
public function zeroFill($a, $b)
    {
        return ($a >= 0) ? ($a >> $b) : ($a >> $b) & (PHP_INT_MAX >> ($b - 1));
    }
697251
public function Multiply($a, $b)
    {
        $this->preOpMethodParamsCheck(array($a, $b));

        return $this->math->mul($a, $b);
    }