Hi all, This is the numeric literals part, reformated to follow Michael's outline.
It has some additions: - Complex numbers - Further explanation of NaN/Inf, with a tentative algebra table. - Caveats when using BigInts/BigRats There are some open questions, but I think I am finally not forgetting any kind of numbers. I am specially interested in the BigInt/BigRats part. It documents the current behaviour (in perl5, using Math::BigInt), but maybe Perl6 will do better. -angel ----------------------------------------- =section * Numeric Literals =section ** Integer and Decimal literals There are many ways to specify literal numeric values in perl, but they default to base 10 for input and output. print 14; print -123.5; =section ** Scientific (or exponential) notation Perl allows you to use the standard scientific notation to represent floating-point literals. For example: my $x = 7.823e6; This notation is designed to let you write very large or very small numbers efficiently. It works just like the standard scientific notation: the left portion of the C<e> is the coefficient, and the right is the exponent, so a number of the form C<C.CCCeEE> is actually intepreted as C<C.CCC * 10**EE>. For example, the literal C<7.828e6> is interpreted as C<7823000>. You can use negative numbers in the exponent side, allowing you to write very small numbers. my $x = 0.00000000000345; my $x = 3.45e-12; # equivalent =section ** Radix Notation For integer numbers, you can represent the literal value in any other base, using the C<radix:dddddddd> syntax. For example: my $i = 2:101110; # binary my $j = 3:1210112; # tertiary my $k = 8:1270; # octal Printing these would give 46, 1310, and 696 respectively. When the base is greater than 10, there is a need to represent digits that are greater than 9. You can do this in two ways: =over =item * Alphabetic characters: Following the standard convention, perl will interpret the A letter as the digit 10, the B letter as digit 11, and so on. my $l = 16:1E3A7; # hexadecimal =item * Separating by dots: You can also write each digit in its decimal representation, and separate digits using the C<.> character. my $m = 256:255.255.255.0; # 256-base =back For example, the integer 30 can be written in hexadecimal base 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 Beware that when writing negative integers, the negative character C<-> should be at the leftest point of the expression: my $z = -256:234.254; # negative number my $e = 256:-234.254; # error Keep in mind that 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 will use decimal base when printing all the numbers, no matter what base did you use to type them. =section ** Underscore character as a seprator Perl allows the underscore character, C<_>, to be placed as a separator between the digits of any literal number. You can use this to break up long numbers into more readable forms. There aren't any rules to it; you can use it however you like: 123_456_000.000 (floating point) 2:0110_1000 (binary) 16:FF_88_EE (hexidecimal) 1312512.25 (decimal number) 1_312_512.25 (the same) You can only insert the C<_> character beween two digits, so this will generate a compile-time error: _2_3_4____5___6 (error) =section ** Complex Numbers Any integer of decimal number, followed by the C<i> letter will be interpreted as an imaginary number. For example: print 2i*3i; # prints -6 This lets you easily create complex numbers: my $z = 2.3 + 1i; The C<1i> and C<-1i> numbers can be also written respectively, C<i> and C<-i>, so the previous example could be rewritten: my $z = 2.3 + i; =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. In operations between C<NaN> and other numbers, the result is always C<NaN> again. print 0 * NaN; # NaN print Nan / NaN; # NaN Moreover, C<NaN> is special in that it is never numerically equal to any number, so even the expression C<NaN == NaN> is false. NOTE: what about C<NaN != NaN>, is it true or false? =section *** Inf The terms C<Inf> and C<-Inf> represent positive and negative infinity; you may sometimes use these to create infinite lists. For the C<Inf> values, perl will operate them following the standard conventions. For example: Operation Result ---------- ------ Inf + $X Inf Inf + Inf Inf Inf - $X Inf Inf - Inf NaN Inf * $P Inf Inf * $N Inf Inf * 0 NaN Inf * Inf Inf Inf / $P Inf Inf / $N -Inf Inf / 0 NaN (or Inf?, but then which sign?) Inf / Inf NaN $P ** Inf Inf $N ** Inf NaN 0 ** Inf 0 Here C<$P> and C<$N> represent respectively any positive and negative values, and C<$X> represents any finite number without restrictions (including complex numbers). NOTE: This table is not complete, but completing it would make it horrible lengthy. Is it really worth? =section * Caveats when using BigNum/BigRats 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 customs types of numbers, such as BigInt (arbitrary size integers) and BigRats (Decimal numbers with a precision level greater than the one of native types). For example: my BigInt $i = 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 is number is stored as a BigInt number it has alreadly lost the last digits. If you need to create BigInt numbers without risking to lose precision, you should write them as a string literals: my BigInt $i = '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 C<$i>, so everything goes well. =seealso String Literals =seealso Typing Variables =seealso BigInt/BigRats reference