Skip to content

Commit

Permalink
Add Math::BigInt.Bool and infix:<**>.
Browse files Browse the repository at this point in the history
  • Loading branch information
colomon committed Jan 30, 2011
1 parent 286b859 commit 5627557
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 2 deletions.
27 changes: 25 additions & 2 deletions lib/Math/BigInt.pm
Expand Up @@ -13,6 +13,7 @@ sub bdModulo(OpaquePointer $w, OpaquePointer $u, OpaquePointer $v) returns Int i
sub bdConvToDecimal(OpaquePointer $bd, OpaquePointer $s, Int $smax) returns Int is native("libbd") { ... }
sub bdIsEqual(OpaquePointer $a, OpaquePointer $b) returns Int is native("libbd") { ... }
sub bdCompare(OpaquePointer $a, OpaquePointer $b) returns Int is native("libbd") { ... }
sub bdIsZero(OpaquePointer $a) returns Int is native("libbd") { ... }

sub malloc(Int $n) returns OpaquePointer is native("libSystem") { ... }
sub free(OpaquePointer $p) is native("libSystem") { ... }
Expand Down Expand Up @@ -46,8 +47,12 @@ class Math::BigInt does Real {
$result;
}

method Bridge() {
+self.Str;
method Bridge(Math::BigInt $x:) {
+$x.Str;
}

method Bool(Math::BigInt $x:) {
!bdIsZero($x.bd);
}

method succ(Math::BigInt $x:) { bdIncrement($x.bd); self; }
Expand Down Expand Up @@ -140,6 +145,24 @@ class Math::BigInt does Real {
bdModulo($result.bd, $a.bd, Math::BigInt.new($b).bd);
$result.Int;
}

multi sub infix:<**>(Math::BigInt $a, Math::BigInt $b is copy) is export(:DEFAULT) {
my $result = Math::BigInt.new("1");
my $power = $a;
loop {
my $r = $b % 2;
if $r {
$result = $result * $power;
}
$b = ($b - $r) div 2;
last unless $b;
}
$result;
}

multi sub infix:<**>(Math::BigInt $a, Int $b) is export(:DEFAULT) {
$a ** Math::BigInt.new($b);
}

# Comparison operators

Expand Down
2 changes: 2 additions & 0 deletions t/01-basic.t
Expand Up @@ -29,13 +29,15 @@ plan *;
is +$b, 22, ".succ works";
$a = $b.pred;
is +$a, 21, ".pred works";
ok $a.Bool, "and 21.Bool is true";

$a++;
is +$a, 22, "Increment works";
isa_ok $a, Math::BigInt, "It's still a BigInt";
$a--;
is +$a, 21, "Decrement works";
isa_ok $a, Math::BigInt, "It's still a BigInt";
nok ($a - $a).Bool, "0 is false";
}

done;
10 changes: 10 additions & 0 deletions t/02-arith.t
Expand Up @@ -121,6 +121,16 @@ plan *;
is $c, 1, "and it's 1";
}

# power!
{
my @powers-of-three := Math::BigInt.new(1), * * 3 ... *;
for ^20 -> $i {
is @powers-of-three[$i], 3¹ ** $i, "3 ** $i agrees (integer power)";
is @powers-of-three[$i], 3¹ ** Math::BigInt.new($i), "3 ** $i agrees (Math::BigInt power)";
}
}





Expand Down

0 comments on commit 5627557

Please sign in to comment.