Hi,
This in an updated version of the numeric literals document. Hopefully
it is consistent with Michael's summary, and with discussions on the
list.
The portions that were wrong (complex numbers, etc..) have been
removed. Other parts (NaN, etc..) are still there, but I think that
they should later moved elsewhere.
I am just not sure that I got it right with the Ints part, see the
separate post about it.
Michael: feel free to edit/add/remove as you need for the integrated
number document.
-angel
-------------------------
=section * Numeric Literals
=section ** Integer and Decimal literals
There are many ways to specify literal numeric values in
Perl, but the default is to use base 10 for both input and
output.
14
-123.5
=section ** Scientific (or exponential) notation
Perl allows you to use standard scientific notation
to represent floating-point literals. For example:
7.823e6
This notation is designed to let you write very large or
very small numbers efficiently. The left portion of the
C<e> is the coefficient, and the right is the exponent,
so a number of the form C<C.CCCeXX> is actually intepreted
as C<C.CCC * 10**XX>.
You may use either upper or lowercase 'e' as the exponent
marker, so, for example, 3.6e3 is the same as 3.6E3.
Some examples:
7.828e6 # equivalent to 7828000
7.828E6 # the same
3.45e-12 # 0.00000000000345
=section ** Radix Notation
Perl lets you write numbers in any base just by prepending
the radix and a C<#> to the literal.
For example:
2#101110 # binary
2#0.1 # fractional binary
3#1210112 # tertiary
8#1270 # octal
Printing these would give 46, 0.5, 1310, and 696
respectively.
This is because once the number has been read by Perl
it becomes just a magnitude. That is, it loses all trace of
the way it was originally represented and is just a number.
Perl always uses decimal for printing numbers, regardless of
what base you used to enter them.
(See the section "Number to String Conversion" for information
about how to costumize the string representation of numbers)
When the base is greater than 10, there is a need to
represent digits that are greater than 9. This can be done in
two ways:
=over
=item *
Alphanumeric digits: Following the common practice,
perl will interpret the A letter as the digit 10, the B
letter as digit 11, and so on. Alphanumeric digits are case
insensitive:
16#1E3A7 # base 16
16:1e3a5 # the same
This won't work for bases greater than 36, so we
have too:
=item *
Colon Form: You can also write each digit in its own
decimal representation, and separate digits using the C<:>
character.
my $m = 256#255:255:255:0; # base 256
=back
For example, the integer 30 can be written in base 16
in two equivalent ways:
my $x = 16#1D;
my $x = 16#1:14;
These two representations are incompatible, so writing
something like C<16#D:13> will generate a compile-time
error.
Also note that a compile-time error will be generated
if you specify a "digit" that is larger than your radix
can support. For instance,
my $x = 3#23; # error; can't use digit '3' in base 3"
Finally, when writing negative integers, be aware that
the minus sign (C<->) must always be the leftmost
character in the literal, which means it will come to
the left of the radix when using radix notation.
my $z = -256#234:254; # negative number
my $e = 256#-234:254; # error
=section *** Bin/Hex/Oct shorthands
Since writing in binary, hexadecimal and octal is a
moderately common operation, Perl offers a shorthand
for them:
0b0110 # bin
0c0123 # oct
0x00ff # hex
0x00fF # hex, == 0x00ff
0x00FF # hex, == 0x00ff
=section ** Underscore character as a seprator
Perl allows the underscore character, C<_>, to be used as
a separator between the digits of any literal number. You
can use this to break up a long number into a more readable
forms.
The only rule is that you may only use underscore between
digits, not between any other characters that is allowed
to appear in a number.
123_456_000.000 # decimal
2#0110_1000 # binary
16#FF_88_EE # hexidecimal
1312512.25 # decimal
1_312_512.25 # the same one
_2_3_4____5___6 # error
1.434_e_45 # erro: this 'e' is not a digit.
=section ** Pseudo-Numbers
=section *** NaN
The value C<NaN> ("Not a Number") may be returned by some
functions or operations to signal that the result of a
calculation (for example, division by zero) cannot be
represented by a numeric value.
Perl follows the IEEE-754 standard in operation between
C<NaN> and other numbers: the result is always C<NaN>.
print 0 * NaN; # NaN
print NaN / NaN; # NaN
print NaN == NaN; # NaN
print NaN != NaN; # NaN
In boolean context (see "Boolean Context") C<NaN> always
evaluates to false so.
=section *** Inf
The terms C<Inf> and C<-Inf> represent positive and
negative infinity; you may sometimes use these to create
infinite lists.
Perl will also operate C<Inf> following the IEEE-754
standard, which means that it in general it will do
what you expect from it. For example:
(In the following table $X represents a finite
number, but not Inf itself or NaN)
Operation Result When
----------- -------- ------
Inf + $X Inf
Inf + Inf Inf
Inf - $X Inf
Inf - Inf NaN
-Inf $X < 0
Inf * $X 0 $X == 0
Inf $X > 0
Inf * Inf Inf
-Inf $X < 0
Inf / $X NaN $X == 0 # +-Inf actually
+Inf $X > 0
Inf / Inf NaN
NaN $X < 0
$X ** Inf 0 0 <= $X < 1
1 $X == 1
Inf $X >= 1
NOTE: are we going to have +-Inf too?
=section * Caveats when using typed variables
All literal numbers are interepreted at compile-time,
before there is any information available about the type
of the variable that will store them.
This can produce undesired effects when working with
custom types of numbers, such as variables typed
as C<Int>.
For example:
my Int $i is bigint = 777_666_555_444_333_222_111;
print $i; # prints 77766655544433300000
This happens because the C<777_666_555_444_333_222_111>
literal is interpreted as an untyped number, and since
it is too big to be stored in the native integer type,
is automatically promoted to the floating point number
C<7.77666555444333e+20>. When this number is
stored in a Int variable it has alreadly lost the last
digits.
If you need to create typed C<Int> numbers without risking
to lose precision, you should write them as a string literals:
my Int $i is bigint = '777_666_555_444_333_222_111';
print $i; # prints 777666555444333222111
In that case the conversion to a number type happens
at run-time, and is controlled by the type of the C<$i>
variable, so everything goes well.