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.