Nimber arithmetic
(or at least, heavily inspired by FreeBasic)
Not limited by integer size. Doesn't rely on twos complement bitwise and.
sub infix:<⊕> (Int $x, Int $y) { $x +^ $y }
sub infix:<⊗> (Int $x, Int $y) {
return $x × $y if so $x|$y < 2;
my $h = exp $x.lsb, 2;
return ($h ⊗ $y) ⊕ (($x ⊕ $h) ⊗ $y) if $x > $h;
return ($y ⊗ $x) if $y.lsb < $y.msb;
return $x × $y unless my $comp = $x.lsb +& $y.lsb;
$h = exp $comp.lsb, 2;
(($x +> $h) ⊗ ($y +> $h)) ⊗ (3 +< ($h - 1))
}
# TESTING
my $upto = 26;
for <⊕>, &infix:<⊕>,
<⊗>, &infix:<⊗>
-> $op, &f {
put " $op │", ^$upto .fmt('%3s'), "\n───┼", '────' x $upto;
-> $r { put $r.fmt('%2s'), ' │', ^$upto .map: { &f($r, $_).fmt('%3s')} } for ^$upto;
put "\n";
}
put "21508 ⊕ 42689 = ", 21508 ⊕ 42689;
put "21508 ⊗ 42689 = ", 21508 ⊗ 42689;
put "2150821508215082150821508 ⊕ 4268942689426894268942689 = ", 2150821508215082150821508 ⊕ 4268942689426894268942689;
put "2150821508215082150821508 ⊗ 4268942689426894268942689 = ", 2150821508215082150821508 ⊗ 4268942689426894268942689;Output:
Last updated
Was this helpful?