Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
tag: 2011.04
Fetching contributors…

Octocat-spinner-32-eaf2f5

Cannot retrieve contributors at this time

file 116 lines (87 sloc) 3.071 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
class Rat is Cool does Real {
    has $.numerator;
    has $.denominator;


    multi method new() {
        self.bless(*, :numerator(0), :denominator(1));

    }

    multi method new(Int $numerator is copy, Int $denominator is copy) {
        if $denominator < 0 {
            $numerator = -$numerator;
            $denominator = -$denominator;
        }
        my $gcd = gcd($numerator, $denominator);
        $numerator = $numerator div $gcd;
        $denominator = $denominator div $gcd;
        self.bless(*, :numerator($numerator), :denominator($denominator));
    }

    multi method nude() { $.numerator, $.denominator; }

    multi method perl() { "$!numerator/$!denominator"; }

    method Bridge() {
        $!denominator == 0 ?? Inf * $!numerator.sign
                           !! $!numerator.Bridge / $!denominator.Bridge;
    }

    method Bool() { $!numerator != 0 ?? Bool::True !! Bool::False }

    method Rat(Real $epsilon = 1.0e-6) { self; }

    method Num() {
        $!denominator == 0 ?? Inf * $!numerator.sign
                           !! $!numerator.Num / $!denominator.Num;
    }

    method succ {
        Rat.new($!numerator + $!denominator, $!denominator);
    }

    method pred {
        Rat.new($!numerator - $!denominator, $!denominator);
    }
}

multi sub prefix:<->(Rat $a) {
    Rat.new(-$a.numerator, $a.denominator);
}

multi sub infix:<+>(Rat $a, Rat $b) {
    my $gcd = gcd($a.denominator, $b.denominator);
    ($a.numerator * ($b.denominator div $gcd) + $b.numerator * ($a.denominator div $gcd))
        / (($a.denominator div $gcd) * $b.denominator);
}

multi sub infix:<+>(Rat $a, Int $b) {
    ($a.numerator + $b * $a.denominator) / $a.denominator;
}

multi sub infix:<+>(Int $a, Rat $b) {
    ($a * $b.denominator + $b.numerator) / $b.denominator;
}

multi sub infix:<->(Rat $a, Rat $b) {
    my $gcd = gcd($a.denominator, $b.denominator);
    ($a.numerator * ($b.denominator div $gcd) - $b.numerator * ($a.denominator div $gcd))
        / (($a.denominator div $gcd) * $b.denominator);
}

multi sub infix:<->(Rat $a, Int $b) {
    ($a.numerator - $b * $a.denominator) / $a.denominator;
}

multi sub infix:<->(Int $a, Rat $b) {
    ($a * $b.denominator - $b.numerator) / $b.denominator;
}

multi sub infix:<*>(Rat $a, Rat $b) {
    ($a.numerator * $b.numerator) / ($a.denominator * $b.denominator);
}

multi sub infix:<*>(Rat $a, Int $b) {
    ($a.numerator * $b) / $a.denominator;
}

multi sub infix:<*>(Int $a, Rat $b) {
    ($a * $b.numerator) / $b.denominator;
}

multi sub infix:</>(Rat $a, Rat $b) {
    ($a.numerator * $b.denominator) / ($a.denominator * $b.numerator);
}

multi sub infix:</>(Rat $a, Int $b) {
    $a.numerator / ($a.denominator * $b);
}

multi sub infix:</>(Int $a, Rat $b) {
    ($b.denominator * $a) / $b.numerator;
}

multi sub infix:</>(Int $a, Int $b) {
    Rat.new($a, $b);
}

multi sub infix:<**>(Rat $a, Int $b) {
    my $num = $a.numerator ** $b;
    my $den = $a.denominator ** $b;
    $num ~~ Int && $den ~~ Int ?? $num / $den !! $a.Bridge ** $b;
}

# vim: ft=perl6 sw=4 ts=4 expandtab
Something went wrong with that request. Please try again.