role Real
role Real does Numeric { ... }
Common role for non-Complex numbers.
Methods
method Bridge
method Bridge(Real:D:)
Default implementation coerces the invocant to Num and that's the behavior
of this method in core Real
types. This method primarily exist to make it
easy to implement custom Real
types by users, with the Bridge
method
returning one of the core Real
types (NOT necessarily a Num)
that best represent the custom Real
type. In turn, this lets all the
core operators and methods obtain a usable value they can work with.
As an example, we can implement a custom Temperature
type. It has a unit of
measure and the value, which are given during instantiation. We can implement
custom operators or conversion methods that work with this type. When it comes
to regular mathematical operators, however, we can simply use the .Bridge
method to convert the Temperature
to Kelvin expressed in one of the core
numeric types:
class Temperature is Real {
has Str:D $.unit is required where any <K F C>;
has Real:D $.value is required;
method new ($value, :$unit = 'K') { self.bless :$value :$unit }
# Note: implementing .new() that handles $value of type Temperature is left as an exercise
method Bridge {
when $!unit eq 'F' { ($!value + 459.67) × 5/9 }
when $!unit eq 'C' { $!value + 273.15 }
$!value
}
method gist { self.Str }
method Str { "$!value degrees $!unit" }
}
sub postfix:<℃> { Temperature.new: $^value, :unit<C> }
sub postfix:<℉> { Temperature.new: $^value, :unit<F> }
sub postfix:<K> { Temperature.new: $^value, :unit<K> }
my $human := 36.6℃;
my $book := 451℉;
my $sun := 5778K;
say $human; # OUTPUT: «36.6 degrees C»
say $human + $book + $sun; # OUTPUT: «6593.677777777778»
say 123K + 456K; # OUTPUT: «579»
As we can see from the last two lines of the output, the type of the bridged
result is not forced to be any particular core type. It is a Rat, when we
instantiated Temperature
with a Rat or when conversion was involved, and
it is an Int when we instantiated Temperature
with an Int.
method Complex
method Complex(Real:D: --> Complex:D)
Converts the number to a Complex with the number converted to a Num as its real part and 0e0 as the imaginary part.
method Int
method Int(Real:D:)
Calls the Bridge method on the invocant and then the Int method on its return value.
method Rat
method Rat(Real:D: Real $epsilon = 1e-6)
Calls the Bridge method on the invocant and then
the Rat method on its return value with the
$epsilon
argument.
method Real
multi method Real(Real:D: --> Real:D)
multi method Real(Real:U: --> Real:D)
The :D
variant simply returns the invocant. The :U
variant issues a
warning about using an uninitialized value in numeric context and then returns
self.new
.
method Str
multi method Str(Real:D:)
Calls the Bridge method on the invocant and then the Str method on its return value.
method Num
method Num(Real:D:)
Calls the Bridge method on the invocant and then the Num method on its return value.
routine rand
sub term:<rand> (--> Num:D)
method rand(Real:D: --> Real:D)
Returns a pseudo-random number between zero (inclusive) and the number
(non-inclusive). The Bridge method is used to coerce the
Real
to a numeric that supports rand method.
The term form returns a pseudo-random Num between 0e0 (inclusive) and 1e0 (non-inclusive.)
method sign
method sign(Real:D:)
Returns -1
if the number is negative, 0
if it is zero and 1
otherwise.
method round
method round(Real:D: $scale = 1)
Rounds the number to scale $scale
. If $scale
is 1, rounds to an
integer. If scale is 0.1
, rounds to one digit after the radix point (period or comma), etc.
method floor
method floor(Real:D: --> Int:D)
Return the largest integer not greater than the number.
method ceiling
method ceiling(Real:D: --> Int:D)
Returns the smallest integer not less than the number.
method truncate
method truncate(Real:D: --> Int:D)
Rounds the number towards zero.
method polymod
method polymod(Real:D: +@mods)
Returns the remainders after applying sequentially all divisors in the @mods
argument; the last element of the array will be the last remainder.
say (1e8+1).polymod(10 xx 8); # OUTPUT: «(1 0 0 0 0 0 0 0 1)»
10 xx 8
is simply an array with eight number 10s; the first division by 10
will return 1
as a remainder, while the rest, up to the last, will return 0.
With 8 divisors, as above, the result will have one more elements, in this case
for the last remainder.
say ⅔.polymod(⅓); # OUTPUT: «(0 2)»
say 5.Rat.polymod(.3, .2); # OUTPUT: «(0.2 0 80)»
method base
method base(Real:D: Int:D $base where 2..36, $digits? --> Str:D)
Converts the number to a string, using $base
as base. For $base
larger
than ten, capital Latin letters are used.
255.base(16); # 'FF'
The optional $digits
argument asks for that many digits of fraction (which
may not be negative). If omitted, a reasonable default is chosen based on type.
For Int this default is 0. For Num, the default is 8. For
Rational, the number of places is scaled to the size of the
denominator, with a minimum of 6.
A special value of Whatever (*
) can be given as
$digits
, which functions the same as when $digits
is not specified for all
Real
types except the Rationals. For Rationals, the Whatever
indicates that you wish all of the possible digits of the fractional part, but
use caution: since there's no detection of repeating fractional parts (the
algorithm will eventually stop after generating 2**63 digits).
The final digit produced is always rounded.
say pi.base(10, 3); # OUTPUT: «3.142»
say (1/128).base(10, *); # OUTPUT: «0.0078125»
say (1/100).base(10, *); # OUTPUT: «0.01»
say (1/3) .base(10, *); # WRONG: endlessly repeating fractional part
For reverse operation, see parse-base