X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=pod%2Fperlfaq4.pod;h=bcf03990bc6eef7d178935d3e14118b80acdf0fb;hb=1b3f7d2103791ceee4a17b0f9f5860baa1512c7a;hp=34b7e5b0f3e0fa6d01cb713c01eda6830f00141f;hpb=3fe9a6f19eb206c685bd7389e54e2838fdfd04b7;p=p5sagit%2Fp5-mst-13.2.git diff --git a/pod/perlfaq4.pod b/pod/perlfaq4.pod index 34b7e5b..bcf0399 100644 --- a/pod/perlfaq4.pod +++ b/pod/perlfaq4.pod @@ -1,6 +1,6 @@ =head1 NAME -perlfaq4 - Data Manipulation ($Revision: 1.17 $, $Date: 1997/03/25 18:16:24 $) +perlfaq4 - Data Manipulation ($Revision: 1.19 $, $Date: 1997/04/24 22:43:57 $) =head1 DESCRIPTION @@ -10,6 +10,34 @@ data issues. =head1 Data: Numbers +=head2 Why am I getting long decimals (eg, 19.9499999999999) instead of the numbers I should be getting (eg, 19.95)? + +Internally, your computer represents floating-point numbers in binary. +Floating-point numbers read in from a file, or appearing as literals +in your program, are converted from their decimal floating-point +representation (eg, 19.95) to the internal binary representation. + +However, 19.95 can't be precisely represented as a binary +floating-point number, just like 1/3 can't be exactly represented as a +decimal floating-point number. The computer's binary representation +of 19.95, therefore, isn't exactly 19.95. + +When a floating-point number gets printed, the binary floating-point +representation is converted back to decimal. These decimal numbers +are displayed in either the format you specify with printf(), or the +current output format for numbers (see L if you use +print. C<$#> has a different default value in Perl5 than it did in +Perl4. Changing C<$#> yourself is deprecated. + +This affects B computer languages that represent decimal +floating-point numbers in binary, not just Perl. Perl provides +arbitrary-precision decimal numbers with the Math::BigFloat module +(part of the standard Perl distribution), but mathematical operations +are consequently slower. + +To get rid of the superfluous digits, just use a format (eg, +C) to get the required precision. + =head2 Why isn't my octal data interpreted correctly? Perl only understands octal and hex numbers as such when they occur @@ -36,10 +64,12 @@ The POSIX module (part of the standard perl distribution) implements ceil(), floor(), and a number of other mathematical and trigonometric functions. -The Math::Complex module (part of the standard perl distribution) -defines a number of mathematical functions that can also work on real -numbers. It's not as efficient as the POSIX library, but the POSIX -library can't work with complex numbers. +In 5.000 to 5.003 Perls, trigonometry was done in the Math::Complex +module. With 5.004, the Math::Trig module (part of the standard perl +distribution) implements the trigonometric functions. Internally it +uses the Math::Complex module and some functions can break out from +the real axis into the complex plane, for example the inverse sine of +2. Rounding in financial applications can have serious implications, and the rounding method used should be specified precisely. In these @@ -199,6 +229,9 @@ arbitrary expressions: print "That yields ${\($n + 5)} widgets\n"; +See also "How can I expand variables in text strings?" in this section +of the FAQ. + =head2 How do I find matching/nesting anything? This isn't something that can be tackled in one regular expression, no @@ -234,6 +267,9 @@ Use Text::Wrap (part of the standard perl distribution): use Text::Wrap; print wrap("\t", ' ', @paragraphs); +The paragraphs you give to Text::Wrap may not contain embedded +newlines. Text::Wrap doesn't justify the lines (flush-right). + =head2 How can I access/change the first N letters of a string? There are many ways. If you just want to grab a copy, use @@ -289,6 +325,18 @@ To make the first letter of each word upper case: $line =~ s/\b(\w)/\U$1/g; +This has the strange effect of turning "C" into "C". Sometimes you might want this, instead (Suggested by Brian +Foy Ecomdog@computerdog.comE): + + $string =~ s/ ( + (^\w) #at the beginning of the line + | # or + (\s\w) #preceded by whitespace + ) + /\U$1/xg; + $string =~ /([\w']+)/\u\L$1/g; + To make the whole line upper case: $line = uc($line); @@ -321,6 +369,11 @@ suggests (assuming your string is contained in $text): }gx; push(@new, undef) if substr($text,-1,1) eq ','; +If you want to represent quotation marks inside a +quotation-mark-delimited field, escape them with backslashes (eg, +C<"like \"this\""). Unescaping them is a task addressed earlier in +this section. + Alternatively, the Text::ParseWords module (part of the standard perl distribution) lets you say: @@ -368,6 +421,9 @@ substitution: Which is bizarre enough that you'll probably actually need an EEG afterwards. :-) +See also "How do I expand function calls in a string?" in this section +of the FAQ. + =head2 What's wrong with always quoting "$vars"? The problem is that those double-quotes force stringification, @@ -668,7 +724,7 @@ that's come to be known as the Schwartzian Transform: @sorted = map { $_->[0] } sort { $a->[1] cmp $b->[1] } - map { [ $_, uc((/\d+\s*(\S+) )[0] ] } @data; + map { [ $_, uc((/\d+\s*(\S+)/ )[0] ] } @data; If you need to sort on several fields, the following paradigm is useful. @@ -938,6 +994,14 @@ it on top of either DB_File or GDBM_File. Use the Tie::IxHash from CPAN. + use Tie::IxHash; + tie(%myhash, Tie::IxHash); + for ($i=0; $i<20; $i++) { + $myhash{$i} = 2*$i; + } + @keys = keys %myhash; + # @keys = (0,1,2,3,...) + =head2 Why does passing a subroutine an undefined element in a hash create it? If you say something like: @@ -955,8 +1019,7 @@ Normally, merely accessing a key's value for a nonexistent key does I cause that key to be forever there. This is different than awk's behavior. -=head2 How can I make the Perl equivalent of a C structure/C++ class/hash -or array of hashes or arrays? +=head2 How can I make the Perl equivalent of a C structure/C++ class/hash or array of hashes or arrays? Use references (documented in L). Examples of complex data structures are given in L and L. Examples of @@ -983,7 +1046,7 @@ versus "binary" files. See L. If you're concerned about 8-bit ASCII data, then see L. -If you want to deal with multi-byte characters, however, there are +If you want to deal with multibyte characters, however, there are some gotchas. See the section on Regular Expressions. =head2 How do I determine whether a scalar is a number/whole/integer/float? @@ -994,7 +1057,7 @@ Assuming that you don't care about IEEE notations like "NaN" or warn "has nondigits" if /\D/; warn "not a whole number" unless /^\d+$/; warn "not an integer" unless /^-?\d+$/; # reject +3 - warn "not an integer" unless /^[+-]?\d+$/; + warn "not an integer" unless /^[+-]?\d+$/; warn "not a decimal number" unless /^-?\d+\.?\d*$/; # rejects .2 warn "not a decimal number" unless /^-?(?:\d+(?:\.\d*)?|\.\d+)$/; warn "not a C float" @@ -1035,3 +1098,4 @@ Get the Business::CreditCard module from CPAN. Copyright (c) 1997 Tom Christiansen and Nathan Torkington. All rights reserved. See L for distribution information. +