在Perl中,如何限制小数点后的位数,但没有尾随的零?

在Perl中,如何限制小数点后的位数,但没有尾随的零?,perl,printf,decimal-point,Perl,Printf,Decimal Point,这个问题类似于,但对于Perl和,小数点后有最大位数 我正在寻找一种将数字转换为字符串格式的方法,删除任何多余的“0”,包括不仅仅是小数点后的数字。并且仍然具有最大数字量,例如3 输入数据是浮动的。期望输出: 0 -> 0 0.1 -> 0.1 0.11 -> 0.11 0.111 -> 0.111 0.1111111 -> 0.111 直接使用以下命令: my $s = sprintf('%.3f', $f); $s

这个问题类似于,但对于Perl和,小数点后有最大位数

我正在寻找一种将数字转换为字符串格式的方法,删除任何多余的“0”,包括不仅仅是小数点后的数字。并且仍然具有最大数字量,例如3

输入数据是浮动的。期望输出:

0         -> 0
0.1       -> 0.1
0.11      -> 0.11
0.111     -> 0.111
0.1111111 -> 0.111

直接使用以下命令:

my $s = sprintf('%.3f', $f);
$s =~ s/\.?0*$//;

print $s
…或定义一个子例程以更一般地执行此操作:

sub fstr {
  my ($value,$precision) = @_;
  $precision ||= 3;
  my $s = sprintf("%.${precision}f", $value);
  $s =~ s/\.?0*$//;
  $s
}

print fstr(0) . "\n";
print fstr(1) . "\n";
print fstr(1.1) . "\n";
print fstr(1.12) . "\n";
print fstr(1.123) . "\n";
print fstr(1.12345) . "\n";
print fstr(1.12345, 2) . "\n";
print fstr(1.12345, 10) . "\n";
印刷品:

0
1
1.1
1.12
1.123
1.123
1.12
1.12345

这将为您提供所需的输出:

sub dropTraillingZeros{
$_ = shift;
s/(\d*\.\d{3})(.*)/$1/;
s/(\d*\.\d)(00)/$1/;
s/(\d*\.\d{2})(0)/$1/;
print "$_\n";
}
dropTraillingZeros(0);
dropTraillingZeros(0.1);
dropTraillingZeros(0.11);
dropTraillingZeros(0.111);
dropTraillingZeros(0.11111111);
您还可以使用来执行此操作:

$ perl -MMath::Round=nearest -e 'print nearest(.001, 0.1), "\n"'
0.1
$ perl -MMath::Round=nearest -e 'print nearest(.001, 0.11111), "\n"'
0.111

您可以将
sprintf
eval
结合使用

my $num = eval sprintf('%.3f', $raw_num);
例如:

#!/usr/bin/perl 

my @num_array = (
    0, 1, 1.0, 0.1, 0.10, 0.11, 0.111, 0.1110, 0.1111111
);


for my $raw_num (@num_array) {
    my $num = eval sprintf('%.3f', $raw_num);
    print $num . "\n";
}
产出:

0
1
1
0.1
0.1
0.11
0.111
0.111
0.111

此解决方案仅适用于小数字<代码>打印删除小数部分或在15位之后切换到科学记数法
nearest
可以放大数字中已经存在的任何错误(例如,用
nearest
1111111 29995.56
四舍五入到
.001
产生
1111111 29995.58
,而
sprintf(%.3f”,1111111111111 29995.56)
正确产生
1111111111111 29995.56
)嘿,好问题,这件事我已经想了很多次了!只是一个想法:接受一个更为社区认可的答案!