2009-02-20 17 views
5

Bu soru "dropping trailing ‘.0’ from floats"'a benzer, ancak Perl için ve ondalıktan sonra maksimum sayı sayısıyla.Perl'de, ondalık noktadan sonraki yerlerin sayısını nasıl sınırlandırabilirim, ancak son sıfır noktası yok?

Sayıları dize biçimine dönüştürmenin, ondalıktan hemen sonra değil de dahil olmak üzere herhangi bir yedek '0'ı bırakmanın bir yolunu arıyorum. Ve hala maksimum sayıda dijital ile, ör. 3

Giriş verileri yüzüyor. İstenilen çıktı:

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

cevap

3

için g bunun için:

$ 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' fraksiyonel parçayı düşürür veya 15 basamaktan sonra bilimsel gösterime geçer; "en yakın", numarada zaten mevcut olan herhangi bir hatayı artırabilir (örn. 111111111129995.56 yuvarlamasının ".001" ile "en yakın", "111111111129995.58", "sprintf" ("%. 3f", 111111111129995.56) "ise" 111111111129995.56 "değerini doğru olarak üretir. .) – vladr

18

doğrudan aşağıdaki kullanın:

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

print $s 

... ya da daha genel olarak bunu yapmak için alt yordam tanımlayın:

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

Baskı:

0 
1 
1.1 
1.12 
1.123 
1.123 
1.12 
1.12345 
0

Bu size görünümünüzü verecektir. Ayrıca Math::Round kullanabilirsiniz

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

Sen "eval" ile birlikte "sprintf'i" kullanabilirsiniz. Örneğin

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"; 
} 

çıkışları: Bu çözüm yalnızca küçük sayılar için çalışır

0 
1 
1 
0.1 
0.1 
0.11 
0.111 
0.111 
0.111