| 1 | =head1 NAME
|
|---|
| 2 |
|
|---|
| 3 | perlfaq4 - Data Manipulation ($Revision: 1.73 $, $Date: 2005/12/31 00:54:37 $)
|
|---|
| 4 |
|
|---|
| 5 | =head1 DESCRIPTION
|
|---|
| 6 |
|
|---|
| 7 | This section of the FAQ answers questions related to manipulating
|
|---|
| 8 | numbers, dates, strings, arrays, hashes, and miscellaneous data issues.
|
|---|
| 9 |
|
|---|
| 10 | =head1 Data: Numbers
|
|---|
| 11 |
|
|---|
| 12 | =head2 Why am I getting long decimals (eg, 19.9499999999999) instead of the numbers I should be getting (eg, 19.95)?
|
|---|
| 13 |
|
|---|
| 14 | Internally, your computer represents floating-point numbers
|
|---|
| 15 | in binary. Digital (as in powers of two) computers cannot
|
|---|
| 16 | store all numbers exactly. Some real numbers lose precision
|
|---|
| 17 | in the process. This is a problem with how computers store
|
|---|
| 18 | numbers and affects all computer languages, not just Perl.
|
|---|
| 19 |
|
|---|
| 20 | L<perlnumber> show the gory details of number
|
|---|
| 21 | representations and conversions.
|
|---|
| 22 |
|
|---|
| 23 | To limit the number of decimal places in your numbers, you
|
|---|
| 24 | can use the printf or sprintf function. See the
|
|---|
| 25 | L<"Floating Point Arithmetic"|perlop> for more details.
|
|---|
| 26 |
|
|---|
| 27 | printf "%.2f", 10/3;
|
|---|
| 28 |
|
|---|
| 29 | my $number = sprintf "%.2f", 10/3;
|
|---|
| 30 |
|
|---|
| 31 | =head2 Why is int() broken?
|
|---|
| 32 |
|
|---|
| 33 | Your int() is most probably working just fine. It's the numbers that
|
|---|
| 34 | aren't quite what you think.
|
|---|
| 35 |
|
|---|
| 36 | First, see the above item "Why am I getting long decimals
|
|---|
| 37 | (eg, 19.9499999999999) instead of the numbers I should be getting
|
|---|
| 38 | (eg, 19.95)?".
|
|---|
| 39 |
|
|---|
| 40 | For example, this
|
|---|
| 41 |
|
|---|
| 42 | print int(0.6/0.2-2), "\n";
|
|---|
| 43 |
|
|---|
| 44 | will in most computers print 0, not 1, because even such simple
|
|---|
| 45 | numbers as 0.6 and 0.2 cannot be presented exactly by floating-point
|
|---|
| 46 | numbers. What you think in the above as 'three' is really more like
|
|---|
| 47 | 2.9999999999999995559.
|
|---|
| 48 |
|
|---|
| 49 | =head2 Why isn't my octal data interpreted correctly?
|
|---|
| 50 |
|
|---|
| 51 | Perl only understands octal and hex numbers as such when they occur as
|
|---|
| 52 | literals in your program. Octal literals in perl must start with a
|
|---|
| 53 | leading "0" and hexadecimal literals must start with a leading "0x".
|
|---|
| 54 | If they are read in from somewhere and assigned, no automatic
|
|---|
| 55 | conversion takes place. You must explicitly use oct() or hex() if you
|
|---|
| 56 | want the values converted to decimal. oct() interprets hex ("0x350"),
|
|---|
| 57 | octal ("0350" or even without the leading "0", like "377") and binary
|
|---|
| 58 | ("0b1010") numbers, while hex() only converts hexadecimal ones, with
|
|---|
| 59 | or without a leading "0x", like "0x255", "3A", "ff", or "deadbeef".
|
|---|
| 60 | The inverse mapping from decimal to octal can be done with either the
|
|---|
| 61 | "%o" or "%O" sprintf() formats.
|
|---|
| 62 |
|
|---|
| 63 | This problem shows up most often when people try using chmod(), mkdir(),
|
|---|
| 64 | umask(), or sysopen(), which by widespread tradition typically take
|
|---|
| 65 | permissions in octal.
|
|---|
| 66 |
|
|---|
| 67 | chmod(644, $file); # WRONG
|
|---|
| 68 | chmod(0644, $file); # right
|
|---|
| 69 |
|
|---|
| 70 | Note the mistake in the first line was specifying the decimal literal
|
|---|
|
|---|