Why am I getting long decimals (eg, 19.9499999999999)
instead of the numbers I should be getting (eg, 19.95)?
The infinite set that a mathematician thinks of as the
real numbers can only be approximate on a computer, since
the computer only has a finite number of bits to store an
infinite number of, um, numbers.
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 the section on $# in the
perlvar manpage if you use print. $# has a different
default value in Perl5 than it did in Perl4. Changing $#
yourself is deprecated.
This affects all 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
To get rid of the superfluous digits, just use a format
(eg, printf("%.2f", 19.95)) to get the required precision.
See the section on Floating-point Arithmetic in the perlop
The result of the floating point arithmetic in your script comes out to be
5799.9999999999991; when you truncate that with int(), you end up with
The output is "int(5800) == 5799", which is not what I expect.
The issue is that $value is actually 5799.99999999..., due to the use of
floating point (29/50 is float) and its inherent inaccuracies. Thus, $value2
is getting truncated to 5799.
But the print statement interpolates $value as a string, using the default
representation for floating point, which is rounded at (I think) 6 digits or
so. Hence, you see 5780. To see the lot, use printf: