Can anyone explain how this this:
#!/usr/bin/perl -w
my $amount = 74.32 * 100.00;
printf "Unformatted Amount:${amount}:\n";
printf " Formatted Amount:%.11d:\n", $amount;
Outputs this:
$ ./test.pl
Unformatted Amount:7432:
Formatted Amount:00000007431:
At the moment I've stopped using printf and sprintf as I don't trust them. So I'm doing this instead:
#!/usr/bin/perl -w
my $amount = 74.32 * 100.00;
$formatted_amount = "00000000000" . $amount;
$formatted_amount = substr($formated_amount,length($formatted_amount)-11,11);
printf "Unformatted Amount:${amount}:\n";
printf " Formatted Amount:${formatted_amount}:\n";
which works but curious as to why I need to do this.
I understand how binary numbers cannot exactly represent all base 10 numbers, and have read this Stack Overflow entry: How to eliminate Perl rounding errors, but I honestly did not expect to see a problem with such a seemingly simple example.
Also the value of $amount is correct. It's just printf is not printing it correctly!
Any ideas?
I think printf
should give up on you!
What do you expect a specifier of %.11d
to do?
The value after the decimal point is a precision, and perldoc -f sprintf
says this
For integer conversions, specifying a precision implies that the output of the number itself should be zero-padded to this width, where the 0 flag is ignored
If you want a minimum width of 11 characters than just omit the decimal point - %11d
will give you what you want.
Perl converts floating point numbers to integers by truncating them, and as 74.32 * 100.0
is slightly less than 7432, int(74.32 * 100.0)
is 7431. If you want your floating point value rounded to the nearest integer then use the f
format specifier with a zero precision, like %11.0f
.
To zero-pad a field, take a look at the flags section of the above document. The flag character appears before the width specifier: 0 use zeros, not spaces, to right-justify
.
Check this program
use strict;
use warnings;
my $amount = 74.32 * 100.00;
printf "Unformatted Amount: ${amount}\n";
printf "Truncated Amount: %d\n", $amount;
printf "High-precision Amount: %20.16f\n", $amount;
printf "Rounded Amount: %.0f\n", $amount;
printf "Padded Amount: %011.0f\n", $amount;
output
Unformatted Amount: 7432
Truncated Amount: 7431
High-precision Amount: 7431.9999999999991000
Formatted Amount: 7432
Padded Amount: 00000007432