Skip to content

Commit

Permalink
Rat / FatRat stringification improvements.
Browse files Browse the repository at this point in the history
Borrow TimToady++'s rat stringification code from Rakudo, modify it to allow it to output all decimal digits if requested.  Use that to implement Rat.Str, Rat.perl, and FatRat.Str.
  • Loading branch information
colomon committed Mar 3, 2013
1 parent bdc3343 commit 08a736f
Showing 1 changed file with 42 additions and 1 deletion.
43 changes: 42 additions & 1 deletion lib/CORE.setting
Expand Up @@ -857,11 +857,51 @@ my class Int does Integral {
method expmod($power, $mod) { expmod(self, $power, $mod) }
method is-prime($tries = 100) { is-prime(self, $tries) }
}

sub Niecza::RatToStr ($rat, :$all) {
my $s = $rat.numerator < 0 ?? '-' !! '';
my $r = $rat.abs;
my $i = $r.floor;
$r -= $i;
$s ~= $i;
if $r {
$s ~= '.';
my $want = $rat.denominator < 100_000
?? 6
!! $rat.denominator.Str.chars + 1;
my $f = '';
my $not-done = $all ?? { True } !! { $f.chars < $want };
while $r and $not-done() {
$r *= 10;
$i = $r.floor;
$f ~= $i;
$r -= $i;
}
$f++ if 2 * $r >= 1;
$s ~= $f;
}
$s;
}

my class Rat does Real {
method new($n,$d) { $n / $d }
method immutable() { True }
multi method WHICH(Rat:D:) { ObjAt.new(str => self.perl, ref => self.WHAT) }
method perl() { defined(self) ?? "<" ~ self.numerator ~ "/" ~ self.denominator ~ ">" !! self.typename }
multi method Str() { defined(self) ?? Niecza::RatToStr(self) !! "self.typename" }
method perl() {
return self.typename if !defined(self);
my $den = self.denominator;
$den /= 2 while $den %% 2;
$den /= 5 while $den %% 5;
if $den == 1 {
my $str = Niecza::RatToStr(self, :all);
$str ~= ".0" unless $str ~~ /\./;
$str;
} else {
"<" ~ self.numerator ~ "/" ~ self.denominator ~ ">";
}
}

method gist() { self // nextsame; self.Str }
method numerator() { Q:CgOp { (rat_nu {self}) } }
method denominator() { Q:CgOp { (rat_de {self}) } }
Expand All @@ -886,6 +926,7 @@ my class FatRat does Real {
method new($n,$d) { FatRat.succ * $n / $d }
method immutable() { True }
multi method WHICH(FatRat:D:) { ObjAt.new(str => self.perl, ref => self.WHAT) }
multi method Str() { defined(self) ?? Niecza::RatToStr(self) !! "self.typename" }
method perl() { defined(self) ?? "FatRat.new({self.numerator}, {self.denominator})" !! self.typename }
method FatRat() { self }
method gist() { self // nextsame; self.Str }
Expand Down

0 comments on commit 08a736f

Please sign in to comment.