Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
branch: nom
Fetching contributors…

Cannot retrieve contributors at this time

184 lines (155 sloc) 6.396 kb
my class Complex { ... }
my role Real does Numeric {
method Rat(Real:D: Real $epsilon = 1.0e-6) { self.Bridge.Rat($epsilon) }
method abs() { self < 0 ?? -self !! self }
proto method sign(|) {*}
multi method sign(Real:U:) { Mu }
multi method sign(Real:D:) { self < 0 ?? -1 !! self == 0 ?? 0 !! 1 }
method conj(Real:D:) { self }
method sqrt() { self.Bridge.sqrt }
method rand() { self.Bridge.rand }
method sin() { self.Bridge.sin }
method asin() { self.Bridge.asin }
method cos() { self.Bridge.cos }
method acos() { self.Bridge.acos }
method tan() { self.Bridge.tan }
method atan() { self.Bridge.atan }
proto method atan2(|) {*}
multi method atan2(Real $x = 1e0) { self.Bridge.atan2($x.Bridge) }
multi method atan2(Cool $x = 1e0) { self.Bridge.atan2($x.Numeric.Bridge) }
method sec() { self.Bridge.sec }
method asec() { self.Bridge.asec }
method cosec() { self.Bridge.cosec }
method acosec() { self.Bridge.acosec }
method cotan() { self.Bridge.cotan }
method acotan() { self.Bridge.acotan }
method sinh() { self.Bridge.sinh }
method asinh() { self.Bridge.asinh }
method cosh() { self.Bridge.cosh }
method acosh() { self.Bridge.acosh }
method tanh() { self.Bridge.tanh }
method atanh() { self.Bridge.atanh }
method sech() { self.Bridge.sech }
method asech() { self.Bridge.asech }
method cosech() { self.Bridge.cosech }
method acosech() { self.Bridge.acosech }
method cotanh() { self.Bridge.cotanh }
method acotanh() { self.Bridge.acotanh }
method floor() { self.Bridge.floor }
method ceiling() { self.Bridge.ceiling }
proto method round(|) { * }
multi method round(Real:D:) {
(self + 1/2).floor; # Rat NYI here, so no .5
}
multi method round(Real:D: Real() $scale) {
(self / $scale + 1/2).floor * $scale;
}
method unpolar(Real $angle) {
Complex.new(self * $angle.cos, self * $angle.sin);
}
method cis() {
Complex.new(self.cos, self.sin);
}
method Complex() { Complex.new(self.Num, 0e0) }
proto method log(|) {*}
multi method log(Real:D: ) { self.Bridge.log }
multi method log(Real:D: Real $base) { self.Bridge.log($base.Bridge) }
proto method exp(|) {*}
multi method exp(Real:D: ) { self.Bridge.exp }
method truncate(Real:D:) {
self == 0 ?? 0 !! self < 0 ?? self.ceiling !! self.floor
}
method isNaN { Bool::False }
method polymod(Real:D: *@mods) {
my $more = self;
my $inf = @mods.elems == Inf;
fail X::OutOfRange.new(what => 'invocant to polymod', got => $more, range => "0..*") if $more < 0;
gather {
for @mods -> $mod {
last if $inf and not $more;
fail X::Numeric::DivideByZero.new(using => 'polymod') unless $mod;
take my $rem = $more % $mod;
$more -= $rem;
$more /= $mod;
}
take $more unless $inf;
}
}
method base(Int:D $base, $digits?) {
my $prec = $digits // 1e8.log($base.Num).Int;
my Int $int_part = self.Int;
my $frac = abs(self - $int_part);
my @frac_digits;
my @conversion := <0 1 2 3 4 5 6 7 8 9
A B C D E F G H I J
K L M N O P Q R S T
U V W X Y Z>;
for ^$prec {
last unless $digits // $frac;
$frac = $frac * $base;
push @frac_digits, $frac.Int;
$frac = $frac - $frac.Int;
}
if 2 * $frac >= 1 {
if @frac_digits {
for @frac_digits-1 ... 0 -> $x {
last if ++@frac_digits[$x] < $base;
@frac_digits[$x] = 0;
$int_part++ if $x == 0
}
}
else {
$int_part++;
}
}
my Str $r = $int_part.base($base);
$r ~= '.' ~ @conversion[@frac_digits].join if @frac_digits;
# if $int_part is 0, $int_part.base doesn't see the sign of self
$int_part == 0 && self < 0 ?? '-' ~ $r !! $r;
}
method Real(Real:D:) { self }
method Bridge(Real:D:) { self.Num }
method Int(Real:D:) { self.Bridge.Int }
method Num(Real:D:) { self.Bridge.Num }
multi method Str(Real:D:) { self.Bridge.Str }
method sleep() {
DEPRECATED('sub form of sleep', '2015.02', '2016.01');
sleep self;
}
}
proto sub cis($) {*}
multi sub cis(Real $a) { $a.cis }
multi sub infix:<+>(Real \a, Real \b) { a.Bridge + b.Bridge }
multi sub infix:<->(Real \a, Real \b) { a.Bridge - b.Bridge }
multi sub infix:<*>(Real \a, Real \b) { a.Bridge * b.Bridge }
multi sub infix:</>(Real \a, Real \b) { a.Bridge / b.Bridge }
multi sub infix:<%>(Real \a, Real \b) { a.Bridge % b.Bridge }
multi sub infix:<**>(Real \a, Real \b) { a.Bridge ** b.Bridge }
multi sub infix:«<=>»(Real \a, Real \b) { a.Bridge <=> b.Bridge }
multi sub infix:<==>(Real \a, Real \b) { a.Bridge == b.Bridge }
multi sub infix:«<»(Real \a, Real \b) { a.Bridge < b.Bridge }
multi sub infix:«<=»(Real \a, Real \b) { a.Bridge <= b.Bridge }
multi sub infix:«>»(Real \a, Real \b) { a.Bridge > b.Bridge }
multi sub infix:«>=»(Real \a, Real \b) { a.Bridge >= b.Bridge }
multi sub prefix:<->(Real:D \a) { -a.Bridge }
# NOTE: According to the spec, infix:<mod> is "Not coercive,
# so fails on differing types." Thus no casts here.
proto sub infix:<mod>($, $) {*}
multi sub infix:<mod>(Real $a, Real $b) {
$a - ($a div $b) * $b;
}
multi sub abs(Real \a) {
a < 0 ?? -a !! a;
}
proto sub truncate($) {*}
multi sub truncate(Real:D $x) { $x.truncate }
multi sub truncate(Cool:D $x) { $x.Numeric.truncate }
proto sub atan2($, $?) { * }
multi sub atan2(Real \a, Real \b = 1e0) { a.Bridge.atan2(b.Bridge) }
# should really be (Cool, Cool), and then (Cool, Real) and (Real, Cool)
# candidates, but since Int both conforms to Cool and Real, we'd get lots
# of ambiguous dispatches. So just go with (Any, Any) for now.
multi sub atan2( \a, \b = 1e0) { a.Numeric.atan2(b.Numeric) }
proto sub unpolar($, $) {*}
multi sub unpolar(Real $mag, Real $angle) { $mag.unpolar($angle) }
# vim: ft=perl6 expandtab sw=4
Jump to Line
Something went wrong with that request. Please try again.