Task: Long multiplication






PHP: <?php
function longMult($a, $b)
{
  $as = (string) $a;
  $bs = (string) $b;
  for($pi = 0, $ai = strlen($as) - 1; $ai >= 0; $pi++, $ai--)
    {
      for($p = 0; $p < $pi; $p++)
        {
          $regi[$ai][] = 0;
        }
      for($bi = strlen($bs) - 1; $bi >= 0; $bi--)
        {
          $regi[$ai][] = $as[$ai] * $bs[$bi];
        }
    }
  return $regi;
}

function longAdd($arr)
{
  $outer = count($arr);
  $inner = count($arr[$outer-1]) + $outer;
  for($i = 0; $i <= $inner; $i++)
    {
      for($o = 0; $o < $outer; $o++)
        {
          $val  = isset($arr[$o][$i]) ? $arr[$o][$i] : 0;
          @$sum[$i] += $val;
        }
    }
  return $sum;
}

function carry($arr)
{
  for($i = 0; $i < count($arr); $i++)
    {
      $s = (string) $arr[$i];
      switch(strlen($s))
        {
          case 2:
            $arr[$i] = $s{1};
            @$arr[$i+1] += $s{0};
            break;
          case 3:
            $arr[$i] = $s{2};
            @$arr[$i+1] += $s{0}.$s{1};
            break;
        }
    }
  return ltrim(implode('',array_reverse($arr)),'0');
}

function lm($a,$b)
{
  return carry(longAdd(longMult($a,$b)));
}

if(lm('18446744073709551616','18446744073709551616') == '340282366920938463463374607431768211456')
  {
    echo 'pass!';
  }; // 2^64 * 2^64




COBOL:        identification division.
       program-id. long-mul.
       data division.
       replace ==ij-lim== by ==7== ==ir-lim== by ==14==.
       working-storage section.
       1 input-string pic x(26) value "18,446,744,073,709,551,616".
       1 a-table.
        2 a pic 999 occurs ij-lim.
       1 b-table.
        2 b pic 999 occurs ij-lim.
       1 ir-table value all "0".
        2 occurs ij-lim.
         3 ir pic 999 occurs ir-lim.
       1 s-table value all "0".
        2 s pic 999 occurs ir-lim.
       1 display.
        2 temp-result pic 9(6) value 0.
        2 carry pic 999 value 0.
        2 remain pic 999 value 0.
       1 binary.
        2 i pic 9(4) value 0.
        2 j pic 9(4) value 0.
        2 k pic 9(4) value 0.
       procedure division.
       begin.
           move 1 to j
           perform varying i from 1 by 1 until i > ij-lim
               unstring input-string delimited ","
                   into a (i) with pointer j
           end-perform
           move a-table to b-table
           perform intermediate-calc
           perform sum-ir
           perform display-result
       stop run
       .

       intermediate-calc.
           perform varying i from ij-lim by -1 until i < 1
               move 0 to carry
               perform varying j from ij-lim by -1 until j < 1
                   compute temp-result = a (i) * b (j) + carry
                   divide temp-result by 1000 giving carry
                       remainder remain
                   compute k = i + j
                   move remain to ir (i k)
               end-perform
               subtract 1 from k
               move carry to ir (i k)
           end-perform
           .

       sum-ir.
           move 0 to carry
           perform varying k from ir-lim by -1 until k < 1
               move carry to temp-result
               perform varying i from ij-lim by -1 until i < 1
                   compute temp-result = temp-result + ir (i k)
               end-perform
               divide temp-result by 1000 giving carry
                   remainder remain
               move remain to s (k)
           end-perform
           .

       display-result.
           display "   " input-string
           display " * " input-string
           display " = " with no advancing
           perform varying k from 1 by 1
           until k > ir-lim or s (k) not = 0
           end-perform
           if s (k) < 100
               move 1 to i
               inspect s (k) tallying i for leading "0"
               display s (k) (i:) "," with no advancing
               add 1 to k
           end-if
           perform varying k from k by 1 until k > ir-lim
               display s (k) with no advancing
               if k < ir-lim
                   display "," with no advancing
               end-if
           end-perform
           display space
           .

       end program long-mul.