user
Task

Explicitly implement   long multiplication.

This is one possible approach to arbitrary-precision integer algebra.

For output, display the result of    264 \* 264.

Optionally, verify your result against builtin arbitrary precision support.

The decimal representation of    264    is:

```
18,446,744,073,709,551,616

```

The output of    264 \* 264    is    2128,    and is:

```
340,282,366,920,938,463,463,374,607,431,768,211,456

```
assistant
(formerly Perl 6)

**Works with**: rakudo version 2015-09-17

For efficiency (and novelty), this program explicitly implements long multiplication, but in base 10000. That base was chosen because multiplying two 5-digit numbers can overflow a 32-bit integer, but two 4-digit numbers cannot.

```
sub num_to_groups ( $num ) { $num.flip.comb(/.**1..4/)».flip     };
sub groups_to_num ( @g   ) { [~] flat @g.pop, @g.reverse».fmt('%04d') };

sub long_multiply ( Str $x, Str $y ) {
    my @group_sums;
    for flat num_to_groups($x).pairs X num_to_groups($y).pairs -> $xp, $yp {
        @group_sums[ $xp.key + $yp.key ] += $xp.value * $yp.value;
    }

    for @group_sums.keys -> $k {
        next if @group_sums[$k] < 10000;
        @group_sums[$k+1] += @group_sums[$k].Int div 10000;
        @group_sums[$k] %= 10000;
    }

    return groups_to_num @group_sums;
}

my $str = '18446744073709551616';
long_multiply( $str, $str ).say;

# cross-check with native implementation
say +$str * +$str;

```

Output:

```
340282366920938463463374607431768211456
340282366920938463463374607431768211456

```