```
=encoding utf8
=head1 TITLE
DRAFT: Synopsis 32: Setting Library - Numeric
=head1 AUTHORS
Rod Adams <rod@rodadams.net>
Larry Wall <larry@wall.org>
Aaron Sherman <ajs@ajs.com>
Mark Stosberg <mark@summersault.com>
Carl Mäsak <cmasak@gmail.com>
Moritz Lenz <moritz@faui2k3.org>
Tim Nelson <wayland@wayland.id.au>
=head1 VERSION
Created: 19 Mar 2009 extracted from S29-functions.pod
Last Modified: 16 July 2010
Version: 10
The document is a draft.
If you read the HTML version, it is generated from the Pod in the specs
repository under
L<https://github.com/perl6/specs/blob/master/S32-setting-library/Numeric.pod>
so edit it there in the git repository if you would like to make changes.
This documents Bit, Int, Numeric, Rat, Complex, and Bool.
XXX So where are Bit, Int, and Rat
=head1 Function Packages
=head2 Bool
=over 4
=item succ
our Bool multi method succ ( Bool $b: ) is export
Returns C<Bool::True>.
=item pred
our Bool multi method pred ( Bool $b: ) is export
Returns C<Bool::False>.
=back
=head2 Numeric
C<Numeric> is a role for everything that's a scalar number. So C<Num>, C<Int>,
C<Rat>, C<Complex> and other numeric types do that role. However it is an
abstract interface, so C<$number.WHAT> will never return C<Numeric>.
Users who provide their own scalar numeric types are encouraged to implement the
C<Numeric> role. It is intended that such types such support the basic arithmetic
operators to the extent possible, as well as C<==>. In addition, it is hoped that
comparison operators will at least return consistent results, even if there is no
sensible mathemtical ordering of your type. That allows functions like sort to
not choke and die if they are handed a value of your type. (See also the C<Real>
role for scalar numeric types that represent real numbers.)
The following are all defined in the C<Numeric> role:
C<Numeric> provides some constants in addition to the basic
mathematical functions.
constant pi is export = 3.14159_26535_89793_23846_26433_83279_50288;
constant e is export = 2.71828_18284_59045_23536_02874_71352_66249;
constant i is export = 1i;
=over
=item Real
our Real multi method Real ()
If this C<Numeric> is equivalent to a C<Real>, return that C<Real>.
(For instance, if this number is a C<Complex> with a zero imaginary part.)
Fail otherwise.
=item Int
our Int multi method Int ()
If this C<Numeric> is equivalent to a C<Real>, return the equivalent of
calling C<truncate> on that C<Real> to get an C<Int>.
=item Rat
our Rat multi method Rat ( Real $epsilon = 1.0e-6 )
If this C<Numeric> is equivalent to a C<Real>, return a C<Rat> which is
within C<$epsilon> of that C<Real>'s value.
=item Num
our Num multi method Num ()
If this C<Numeric> is equivalent to a C<Real>, return that C<Real> as a C<Num>
as accurately as is possible.
=item succ
our Numeric multi method succ ( Numeric $x: ) is export
our Int multi method succ ( Int $x: ) is export
Returns the successor of C<$x>. This method is used by C<< prefix:<++> >> and
C<< postfix:<++> >> to increment the value in a container.
=item pred
our Numeric multi method pred ( Numeric $x: ) is export
our Int multi method pred ( Int $x: ) is export
Returns the predecessor of C<$x>. This method is used by C<< prefix:<--> >>
and C<< postfix:<--> >> to decrement the value in a container.
=item abs
our Numeric multi method abs ( Numeric $x: ) is export
Absolute Value.
=item exp
our Numeric multi method exp ( Numeric $exponent: Numeric :$base = Num::e ) is export
Performs similar to C<$base ** $exponent>. C<$base> defaults to the
constant I<e>.
=item log
our Numeric multi method log ( Numeric $x: Numeric $base = Num::e ) is export
Logarithm of base C<$base>, default Natural. Calling with C<$x == 0> is an
error.
=item log10
our Numeric multi method log10 (Numeric $x:) is export
A base C<10> logarithm, otherwise identical to C<log>.
=item rand
our Num term:<rand>
Pseudo random number in range C<< 0 ..^ 1 >>. That is, C<0> is
theoretically possible, while C<1> is not. Note that there is no
unary C<rand> function in Perl 6, but there is a C<rand> method.
For picking a random integer you probably want
to use something like C<(1..6).pick> instead.
=item sqrt
our Numeric multi method sqrt ( Numeric $x: ) is export
Returns the principle square root of the parameter.
=item roots
method roots (Numeric $x: Int $n ) is export
Returns a list of all C<$n>th (complex) roots of C<$x>. Returns C<NaN> if
C<< $n <= 0 >>, itself if C<$n == 0>, and is free to return a single C<NaN>
if C<$x> is C<NaN> or C<Inf>, or in case of complex numbers if one of the
components is.
=item i
our Complex multi postfix:<i> ( Numeric $x )
Returns a complex number representing the parameter multiplied by the imaginary
unit C<i>. Note that there is no C<.i> method. To follow a variable name
with the postfix, it's necessary to use a backslash or parentheses:
$land\i
($land)i
=item to-radians
our Numeric multi method to-radians ( Numeric $x: TrigBase $base ) is export
Convert from C<$base> to radians.
=item from-radians
our Numeric multi method from-radians ( Numeric $x: TrigBase $base ) is export
Convert from radians to C<$base>.
=back
=head2 Real
role Real does Numeric;
C<Real>, like C<Numeric>, is an abstract role that represents the interface of
a real scalar number (i.e. neither C<Complex> nor vector-like). For example
C<Num>, C<Int>, C<Bool> and C<Rat> implement the C<Real> role.
Users who provide their own scalar real numeric types are encouraged to implement the
C<Real> role. Because real numbers are strictly-totally-ordered and
C<Real> types try to emulate that property, it is desirable that any two
C<Real> types be mutally compatible, even if they are not aware of each other. The
current proposal requires you to define a C<Bridge> method in your C<Real> type, which
converts your type into a neutral C<Real> type by restating it in terms of the fundamental
Perl 6 types and calling C<Bridge> on them. This then makes the default C<Real> methods
and operators all work with your C<Real> type. While the name of this method may changed,
it is hoped that something like this will remain in the spec.
=over
=item Complex
our Complex multi method Complex ()
Returns a C<Complex> whose real part is this C<Real> and whose imaginary part is 0.
=item Str
our Str multi method Str ()
Returns the C<Real> as a C<Str>. All built-in C<Real> types format it as a decimal
number, so for example, the C<Rat> C<5/4> is returned as C<"1.2">.
=item floor
our Int multi method floor ( Real $x: ) is export
Returns the highest integer not greater than C<$x>.
=item ceiling
our Int multi method ceiling ( Real $x: ) is export
Returns the lowest integer not less than C<$x>.
=item round
our Int multi method round ( Real $x: $scale = 1) is export
Returns the nearest integer to C<$x>. The algorithm is:
floor($x / $scale + 0.5) * $scale
(Other rounding algorithms will be given extended names beginning with "round".)
Functions that round to a particular precision may easily be created with
currying:
constant &roundcents ::= &round.assuming(:scale(1/100));
=item truncate
our Int multi method truncate ( Real $x: ) is export
Returns the closest integer to C<$x> whose absolute value is not greater
than the absolute value of C<$x>. (In other words, just chuck any
fractional part.) This is the default rounding function used by
implicit integer conversions.
You may also truncate using explicit integer casts, either C<Int()> for
an arbitrarily large integers, or C<int()> for native integers.
=item sign
our Int multi method sign ( Real $x: ) is export
Returns 1 when C<$x> is greater than 0, -1 when it is less than 0, 0 when it
is equal to 0, or undefined when the value passed is undefined.
=item srand
multi srand ( Real $seed = default_seed_algorithm())
Seed the generator C<rand> uses. C<$seed> defaults to some combination
of various platform dependent characteristics to yield a non-deterministic seed.
Note that you get one C<srand()> for free when you start a Perl program, so
you I<must> call C<srand()> yourself if you wish to specify a deterministic seed
(or if you wish to be differently nondeterministic).
=item rand
our Num multi method rand (Real $x:) is export
Pseudo random number in range C<< 0 ..^ $x >>. That is, C<0> is
theoretically possible, while C<$x> is not. For picking a random integer
you probably want to use something like C<(1..6).pick> instead.
=item cis
our Complex multi method cis (Real $angle:) is export
Returns 1.unpolar($angle)
=item unpolar
our Complex multi method unpolar (Real $mag: Real $angle) is export
Returns a complex number specified in polar coordinates. Angle is in radians.
=back
=head2 Num
class Num does Real;
C<Num> is a machine-precision numeric real value.
=head2 Complex
C<Complex> is an immutable type. Each C<Complex> object stores two numbers,
the real and imaginary part. For all practical purposes a C<Complex> with
a C<NaN> in real or imaginary part may be considered a C<NaN> itself (and
C<(NaN + 1i) ~~ NaN> is C<True>).
Coercion of a C<Complex> to any C<Real> returns the real part (coerced, if
necessary) if the imaginary part is 0, and fails otherwise. Comparison
between a C<Real> number and a C<Complex> must be smart enough not to coerce
the C<Complex> to a real number blindly.
=over 4
=item new
our Complex multi method new(Real $re, Real $im)
Constructs a C<Complex> number from real and imaginary part. This is the
method form of C<$re + ($im)i>.
=item polar
our Seq multi method polar (Complex $nim:) is export
Returns (magnitude, angle) corresponding to the complex number.
The magnitude is non-negative, and the angle in the range C<-π ..^ π>.
=item re
our Real multi method re()
Returns the real part of the complex number.
=item im
our Real multi method im()
Returns the imaginary part of a complex number.
=back
=head2 Trigonometric functions
The following are also defined in C<Numeric>. The trig functions
depend on the current (lexically scoped) trig base:
enum TrigBase is export <Radians Degrees Gradians Circles>;
constant $?TRIGBASE = Radians;
=over 4
=item I<Standard Trig Functions>
Numeric multi method func ( Numeric $x: TrigBase $base = CALLER::<$?TRIGBASE> ) is export
where I<func> is one of:
sin, cos, tan, asin, acos, atan, sec, cosec, cotan, asec, acosec,
acotan, sinh, cosh, tanh, asinh, acosh, atanh, sech, cosech, cotanh,
asech, acosech, acotanh.
Performs the various trigonometric functions.
Option C<$base> is used to declare how you measure your angles.
Given the value of an arc representing a single full revolution.
$base Subdivisions of circle
---- ----------------------
Radians 2*pi
Degrees 360
Gradians 400
Circles 1
To change the base within your own lexical scope, it suffices to redefine the
compiler constant with the C<trigbase> pragma:
use trigbase Degrees;
In addition to setting the new lexical C<$?TRIGBASE>, this also
curries a new set of functions into the current lexical scope that
assume the new base. (Note that methods calls cannot be curried, so
methods must still look up the caller's trigbase. The optimizer may,
of course, optimize these into fast function calls.)
=item atan2
our Real multi method atan2 ( Real $y: Real $x = 1, TrigBase $base = CALLER::<$?TRIGBASE> )
our Real multi atan2 ( Real $y, Real $x = 1, TrigBase $base = CALLER::<$?TRIGBASE> )
This second form of C<atan> computes the arctangent of C<$y/$x>, and takes
the quadrant into account. Otherwise behaves as other trigonometric functions.
=back
=head2 Int
An C<Int> is an immutable, integral number of arbitrary size.
=head2 Rat
class Rat does Real;
An immutable rational number, represented by two C<Int>s, a numerator and
a denominator. All interface methods return values as if the numerator and
denominator were stored in a normal form: both numerator and denominator are
minimal in their magnitude, and the denominator is positive. So
C<Rat.new(2, -4).denominator> return C<2>, because the normal form is C<-1/2>.
=over
=item new
multi method new(Int $num, Int $denom)
Constructs a C<Rat> object from the numerator and denominator.
Fails if C<$denom == 0>.
=item nude
our Seq[Int] multi method nude()
Returns a C<Seq> of numerator and denominator
=item denominator
our Int multi method denominator()
Returns the denominator
=item numerator
our Int multi method numerator()
Returns the numerator
=back
=head1 Additions
Please post errors and feedback to perl6-language. If you are making
a general laundry list, please separate messages by topic.
=for vim:set expandtab sw=4:
```