Умножить два целых неотрицательных числа (длинная арифметика)

2 августа 2021
Код на PHP:
<?
/**
 * Класс для сложения и умножения целых неотрицательных чисел
 * @category Длинная арифметика
 */
class Math_long
{
	/**
	 * Складывает два целых неотрицательных числа
	 * @param string $num1 - число 1
	 * @param string $num2 - число 2
	 * @return string
	 */
	static function sum($num1, $num2)
	{
		$r = '';

		$s_max = $num1;
		$s_min = $num2;
		if(strlen($num1)<strlen($num2))
		{
			$s_max = $num2;
			$s_min = $num1;
		}

		$s_max = strrev($s_max);
		$s_min = strrev($s_min);

		$len_max = strlen($s_max);
		$len_min = strlen($s_min);

		$add = 0;
	   	for($i=0; $i<$len_max; $i++)
		{
			$sum = (int)$s_max[$i] + (int)$s_min[$i] + $add;
			$a = $sum % 10;
			$r = $a.$r;

			$add = 0;
			if($sum>=10) $add = 1;
			if($add>0 && $i+1 == $len_max) $r = '1'.$r;
		}

		if($r=='') $r = '0';

		return $r;
	}

	/**
	 * Умножает два целых неотрицательных числа
	 * @param string $num1 - число 1
	 * @param string $num2 - число 2
	 * @return string
	 */
	static function multiply($num1, $num2)
	{
		$r = '0';

		$s_max = $num1;
		$s_min = $num2;
		if(strlen($num1)<strlen($num2))
		{
			$s_max = $num2;
			$s_min = $num1;
		}

		$s_max = strrev($s_max);
		$s_min = strrev($s_min);
		$len_max = strlen($s_max);
		$len_min = strlen($s_min);

		$add = 0;
		$ar_sum = array();
		for($i=0; $i<$len_min; $i++)
		{
			$r_temp = '';
			$add = 0;
			for($k=0; $k<$len_max; $k++)
			{
				$sum = ((int)$s_min[$i] * (int)$s_max[$k]) + $add;

				$a = $sum % 10;
				$ts = ($sum - $a) / 10;
				$r_temp = $a.$r_temp;

				$add = 0;
				if($sum>=10) $add = $ts;
				if($add>0 && $k+1 == $len_max)
				{
					$r_temp = $ts.$r_temp;
				}
			}

			if($r_temp!='' && $r_temp!='0')
			{
				for($m=0; $m<$i; $m++) $r_temp = $r_temp.'0';
				$r = self::sum($r, $r_temp);
			}
		}

		if($r=='') $r = '0';

		return $r;
    }
}

$a = Math_long::multiply('555555555555555555555555555555555555555555555555', '2');
echo $a; //выведет '1111111111111111111111111111111111111111111111110'
?>