Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Updates Rational role's methods with latest nom changes.

Changes Rational's Str method's signature to ::?CLASS:D: to avoid ambiguous dispatches with Real's Str method.
Changes Rational's pred & succ methods to return an object of the same type.
Changes Rat's denominator type to Int. (cheat to avoid setting compilation fail)
Passes the spectests locally.
  • Loading branch information...
commit 09d755cbe1d604d81c13e928b37f123aa17667ca 1 parent 8f76180
@kboga kboga authored
Showing with 93 additions and 11 deletions.
  1. +2 −1  src/core/Rat.pm
  2. +90 −9 src/core/Rational.pm
  3. +1 −1  src/core/UInt64.pm
View
3  src/core/Rat.pm
@@ -1,4 +1,5 @@
-my class Rat is Cool does Rational[Int, UInt64] {
+# XXX: should be Rational[Int, UInt64]
+my class Rat is Cool does Rational[Int, Int] {
method Rat (Rat:D: Real $?) { self }
method FatRat(Rat:D: Real $?) { FatRat.new($.numerator, $.denominator); }
multi method perl(Rat:D:) {
View
99 src/core/Rational.pm
@@ -1,7 +1,20 @@
-my role Rational[::NuT, ::DeT] is Real {
+my role Rational[::NuT, ::DeT] does Real {
has NuT $.numerator;
has DeT $.denominator;
+ multi method WHICH(Rational:D:) {
+ nqp::box_s(
+ nqp::concat_s(
+ nqp::concat_s(nqp::unbox_s(self.^name), '|'),
+ nqp::concat_s(
+ nqp::tostr_I($!numerator),
+ nqp::concat_s('/', nqp::tostr_I($!denominator))
+ )
+ ),
+ ObjAt
+ );
+ }
+
method new(NuT \$nu = 0, DeT \$de = 1) {
my $new := nqp::create(self);
my $gcd := $nu gcd $de;
@@ -20,24 +33,92 @@ my role Rational[::NuT, ::DeT] is Real {
method Num() {
$!denominator == 0
?? ($!numerator < 0 ?? -$Inf !! $Inf)
- !! $!numerator.Num / $!denominator.Num
+ !! nqp::p6box_n(nqp::div_In(
+ nqp::p6decont($!numerator),
+ nqp::p6decont($!denominator)
+ ));
+ }
+
+ method floor(Rational:D:) returns Int:D {
+ $!denominator == 1
+ ?? $!numerator
+ !! $!numerator < 0
+ ?? ($!numerator div $!denominator - 1) # XXX because div for negati
+ !! $!numerator div $!denominator
}
+
+ method ceiling(Rational:D:) returns Int:D {
+ $!denominator == 1
+ ?? $!numerator
+ !! $!numerator < 0
+ ?? ($!numerator div $!denominator) # XXX should be +1, but div is buggy
+ !! ($!numerator div $!denominator + 1)
+ }
+
method Int() { $!numerator div $!denominator }
method Bridge() { self.Num }
- method Rat(Rational:D: Real $?) { self }
- multi method Str(Rational:D:) {
- self.Num.Str
+
+ multi method Str(::?CLASS:D:) {
+ my $s = $!numerator < 0 ?? '-' !! '';
+ my $r = self.abs;
+ my $i = $r.floor;
+ $r -= $i;
+ $s ~= $i;
+ if $r {
+ $s ~= '.';
+ my $want = $!denominator < 100_000
+ ?? 6
+ !! $!denominator.Str.chars + 1;
+ my $f = '';
+ while $r and $f.chars < $want {
+ $r *= 10;
+ $i = $r.floor;
+ $f ~= $i;
+ $r -= $i;
+ }
+ $f++ if 2 * $r >= 1;
+ $s ~= $f;
+ }
+ $s;
}
- multi method perl(Rational:D:) {
- $!numerator ~ '/' ~ $!denominator
+
+ method base($base) {
+ my $s = $!numerator < 0 ?? '-' !! '';
+ my $r = self.abs;
+ my $i = $r.floor;
+ $r -= $i;
+ $s ~= $i.base($base);
+ if $r {
+ my $want = $!denominator < $base**6 ?? 6 !! $!denominator.log($base).ceiling + 1;
+ my @f;
+ while $r and @f < $want {
+ $r *= $base;
+ $i = $r.floor;
+ push @f, $i;
+ $r -= $i;
+ }
+ if 2 * $r >= 1 {
+ for @f-1 ... 0 -> $x {
+ last if ++@f[$x] < $base;
+ @f[$x] = 0;
+ $s ~= ($i+1).base($base) if $x == 0; # never happens?
+ }
+ }
+ $s ~= '.';
+ $s ~= (0..9,'A'..'Z')[@f].join;
+ }
+ $s;
}
+
method succ {
- Rat.new($!numerator + $!denominator, $!denominator);
+ self.new($!numerator + $!denominator, $!denominator);
}
method pred {
- Rat.new($!numerator - $!denominator, $!denominator);
+ self.new($!numerator - $!denominator, $!denominator);
}
+
+ method norm() { self }
}
View
2  src/core/UInt64.pm
@@ -1,2 +1,2 @@
-my $UINT64_UPPER = nqp::pow_I(2, 64, Num);
+my Int $UINT64_UPPER = nqp::pow_I(2, 64, Num, Int);
subset UInt64 of Int where { 0 <= $_ < $UINT64_UPPER }
Please sign in to comment.
Something went wrong with that request. Please try again.