Bar*_*ard 1 perl printf rounding-error
谁能解释一下这是怎么回事:
#!/usr/bin/perl -w
my $amount = 74.32 * 100.00;
printf "Unformatted Amount:${amount}:\n";
printf " Formatted Amount:%.11d:\n", $amount;
Run Code Online (Sandbox Code Playgroud)
输出这个:
$ ./test.pl
Unformatted Amount:7432:
Formatted Amount:00000007431:
Run Code Online (Sandbox Code Playgroud)
目前我已经停止使用 printf 和 sprintf 因为我不信任它们。所以我正在这样做:
#!/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";
Run Code Online (Sandbox Code Playgroud)
这有效,但很好奇为什么我需要这样做。
我了解二进制数字如何无法准确表示所有以 10 为基数的数字,并且已阅读此 Stack Overflow 条目:如何消除 Perl 舍入错误,但老实说,我没想到会在如此看似简单的示例中看到问题。
$amount 的值也是的。只是 printf 没有正确打印它!
有任何想法吗?
我想printf应该放弃你了!
您期望 的说明符%.11d做什么?
小数点后的值是精度,perldoc -f sprintf表示这个
对于整数转换,指定精度意味着数字本身的输出应该用零填充到此宽度,其中 0 标志被忽略
如果您想要11 个字符的最小宽度,那么只需省略小数点 -%11d就会给您您想要的。
Perl 通过截断浮点数将其转换为整数,稍小于7432 的是 7431。如果您希望浮点值四舍五入到最接近的整数,74.32 * 100.0请使用零精度的格式说明符,例如。int(74.32 * 100.0)f%11.0f
要对字段进行零填充,请查看上述文档的标志部分。标志字符出现在宽度说明符之前:0 use zeros, not spaces, to right-justify。
检查这个程序
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;
Run Code Online (Sandbox Code Playgroud)
输出
Unformatted Amount: 7432
Truncated Amount: 7431
High-precision Amount: 7431.9999999999991000
Formatted Amount: 7432
Padded Amount: 00000007432
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
853 次 |
| 最近记录: |