【问题标题】:In Perl, how can I limit the number of places after the decimal point but have no trailing zeroes?在 Perl 中,如何限制小数点后的位数但没有尾随零?
【发布时间】:2020-05-10 11:55:39
【问题描述】:

这个问题类似于"dropping trailing ‘.0’ from floats",但针对 Perl 并且有小数点后的最大位数。

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

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

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

【问题讨论】:

  • 嘿,好问题,我已经多次想到这个问题了!只是一个想法:接受更多社区认可的答案!

标签: perl printf decimal-point


【解决方案1】:

直接使用以下:

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

【讨论】:

    【解决方案2】:

    您也可以使用Math::Round 来执行此操作:

    $ 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
    

    【讨论】:

    • 此解决方案仅适用于小数字。 print 15位后去掉小数部分或全部转为科学计数法; nearest 可以放大数字中已经存在的任何错误(例如,用nearest111111111129995.56 舍入到.001 会产生111111111129995.58,而sprintf("%.3f", 111111111129995.56) 会正确产生111111111129995.56。)
    【解决方案3】:

    您可以将sprintfeval 结合使用。

    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
    

    【讨论】:

      【解决方案4】:

      这将为您提供您正在寻找的输出:

      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);
      

      【讨论】:

        猜你喜欢
        • 2021-09-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多