2009-02-20 708 views
5

這個問題類似於"dropping trailing ‘.0’ from floats",但是對於Perl和小數點後的最大位數。在Perl中,如何限制小數點後的位數,但沒有尾隨零?

我正在尋找一種方法來將數字轉換爲字符串格式,刪除任何多餘的'0',包括不僅在小數點後面。並且仍然具有最大數量的數字,例如3

輸入數據是浮點數。所需的輸出:

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

回答

3

您還可以使用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 
+1

此解決方案僅適用於小的數字。 `print`在15位數字後全部刪除小數部分或切換到科學記數法; 「最接近」可以放大數字中已經存在的任何錯誤(例如,將`111111111129995.56`修整爲`.001`與`nearest`產生`111111111129995.58`,而`sprintf(「%。3f」,111111111129995.56)`正確產生`111111111129995.56` 。) – vladr 2010-03-24 02:45:43

18

直接使用下列內容:

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 
0

這會給你看你的輸出g下,

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

您可以使用 「的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 
相關問題