Skip to content

Commit f644d9d

Browse files
committed
Start writing Numerics guide
1 parent 452aba1 commit f644d9d

File tree

1 file changed

+128
-0
lines changed

1 file changed

+128
-0
lines changed

doc/Language/numerics.pod6

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
=begin pod :tag<perl6>
2+
3+
=TITLE Numerics
4+
5+
=SUBTITLE Numeric types available in Perl 6
6+
7+
=head1 C<Int>
8+
9+
The C<Int> type offers arbitrary-size integer numbers. They can get as big
10+
as your computer memory allows, although some implementations choose to
11+
throw a numeric overflow error when asked to produce integers of truly
12+
staggering size:
13+
14+
=begin code :skip-test<compile-time constant folding will throw example error>
15+
say 10**600**600
16+
# OUTPUT: «Numeric overflow␤»
17+
=end code
18+
19+
Unlike some languages, division performed using
20+
L<C«/» operator|/routine/$SOLIDUS> when both operands are of L<Int>
21+
type, would produce a fractional number, without any rounding performed.
22+
23+
=begin code
24+
say 4/5; # OUTPUT: «0.8␤»
25+
=end code
26+
27+
The type produced by this division is either a L<Rat> or a L<Num> type. The
28+
L<Rat> is produced if, after reduction, the fraction's denominator is smaller
29+
than 64 bits, otherwise a L<Num> type is produced.
30+
31+
The L<div> and L<narrow> routines can be helpful if you wish to end
32+
up with an L<Int> result, whenever possible. The L<div> operator performs
33+
integer division, discarding the remainder, while L<narrow> fits the number
34+
into the narrowest type it'll fit:
35+
36+
=begin code
37+
say 5 div 2; # OUTPUT: «2␤»
38+
39+
# Result `2` is narrow enough to be an Int:
40+
say (4/2).narrow; # OUTPUT: «2␤»
41+
say (4/2).narrow.^name; # OUTPUT: «Int␤»
42+
43+
# But 2.5 has fractional part, so it ends up being a Rat type:
44+
say (5/2).narrow.^name; # OUTPUT: «Rat␤»
45+
say (5/2).narrow; # OUTPUT: «2.5␤»
46+
47+
# Denominator is too big for a Rat, so a Num is produced:
48+
say 1 / 10⁹⁹; # OUTPUT: «1e-99␤»
49+
=end code
50+
51+
Perl 6 has L<FatRat> type that offers arbitrary precision fractions. How come
52+
a limited-precision L<Num> is produced instead of a L<FatRat> type in the
53+
last example above? The reason is: performance. Most operations are fine
54+
with a little bit of precision lost and so do not require the use of a more
55+
expensive L<FatRat> type. You'll need to instantiate one yourself if you wish
56+
to have the extra precision.
57+
58+
=head1 C<Num>
59+
60+
The L<Num> type offers
61+
L<double-precision floating-point|https://en.wikipedia.org/wiki/Double-precision_floating-point_format> decimal numbers, sometimes called "doubles" in other languages.
62+
63+
A L<Num> literal is written with the exponent separated using letter C<e>. Keep
64+
in mind that letter C<e> B<is required> even if the exponent is zero, as
65+
otherwise you'll get a L<Rat> or L<MidRat> rational literal instead:
66+
67+
=begin code
68+
say 42e0.^name; # OUTPUT: «Num␤»
69+
say 42.0.^name; # OUTPUT: «Rat␤»
70+
=end code
71+
72+
Case-sensitive words L<Inf> and L<NaN> represent special values infinity and
73+
not-a-number respectively. The U+221E INFINITY (C<>) character can be used
74+
instead of L<Inf>:
75+
76+
Perl 6 follows the
77+
L<IEEE 754-2008 Standard for Floating-Point Arithmetic|https://en.wikipedia.org/wiki/IEEE_754> as much as possible, with
78+
more conformance planned to be implemented in later language versions. The
79+
language guarantees the closest representable number is chosen for any given
80+
L<Num> literal and does offer support for
81+
L<denormals|https://en.wikipedia.org/wiki/Denormal_number> (also known as
82+
"subnormals").
83+
84+
Keep in mind that output routines like L<say> or L<put> do not try very hard to
85+
distinguish between how L<Numeric> types are output and may choose to display
86+
a L<Num> as an L<Int> or a L<Rat> number. For a more definitive string to
87+
output, use the L<perl> method:
88+
89+
=begin code
90+
say 1e0; # OUTPUT: «1␤»
91+
say .5e0; # OUTPUT: «0.5␤»
92+
say 1e0.perl; # OUTPUT: «1e0␤»
93+
say .5e0.perl; # OUTPUT: «0.5e0␤»
94+
=end code
95+
96+
=head1 C<Complex>
97+
98+
Complex numbers.
99+
100+
=head1 C<Rational>
101+
102+
Rational, high--precision and arbitrary-precision decimal numbers.
103+
104+
=head2 C<Rat>
105+
106+
=head2 C<MidRat>
107+
108+
=head2 C<FatRat>
109+
110+
=head1 Allomorphs
111+
112+
=head2 C<IntStr>
113+
=head2 C<NumStr>
114+
=head2 C<ComplexStr>
115+
=head2 C<RatStr>
116+
=head2 C<MidRatStr>
117+
118+
=head1 Native
119+
120+
=head2 C<int>, C<int8>, C<int16>, C<int32>, and C<int64>
121+
122+
=head2 C<num>, C<num32>, and C<int64>
123+
124+
=head1 Numeric Infectiousness
125+
126+
=end pod
127+
128+
# vim: expandtab softtabstop=4 shiftwidth=4 ft=perl6

0 commit comments

Comments
 (0)