2009-02-20 32 views
5

Câu hỏi này tương tự như "dropping trailing ‘.0’ from floats", nhưng đối với Perl và có số chữ số tối đa sau dấu thập phân.Trong Perl, làm thế nào tôi có thể giới hạn số lượng vị trí sau dấu thập phân nhưng không có số 0 dấu?

Tôi đang tìm cách chuyển đổi số thành định dạng chuỗi, bỏ mọi dự phòng '0', bao gồm không chỉ sau dấu thập phân. Và vẫn với số lượng tối đa của kỹ thuật số, ví dụ: 3

Dữ liệu đầu vào là nổi. đầu ra mong muốn:

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

Trả lời

3

Bạn cũng có thể sử dụng Math::Round để làm điều này:

$ 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

Giải pháp này chỉ có tác dụng đối với số lượng nhỏ. 'print' giảm phần phân đoạn hoặc chuyển sang ký hiệu khoa học hoàn toàn sau 15 chữ số; 'gần nhất' có thể khuyếch đại bất kỳ lỗi nào đã có trong số đó (ví dụ làm tròn số '111111111129995.56' thành' .001' với 'gần nhất' tạo' 111111111129995.58', trong khi 'sprintf ("%. 3f ", 111111111129995.56)' sản xuất chính xác '111111111129995.56' .) – vladr

18

Sử dụng sau đây trực tiếp:

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

print $s 

... hoặc xác định một chương trình con để làm điều đó quát hơ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"; 

Prints:

0 
1 
1.1 
1.12 
1.123 
1.123 
1.12 
1.12345 
0

Điều này sẽ cung cấp cho bạn đầu ra 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

Bạn có thể sử dụng "sprintf" kết hợp với "eval".

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

Ví dụ:

#!/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ết quả đầu ra:

0 
1 
1 
0.1 
0.1 
0.11 
0.111 
0.111 
0.111 
Các vấn đề liên quan