Dưới đây là một kịch bản perl:Tại sao Perl không phù hợp với làm tròn sprintf?
#!/usr/bin/perl
use strict;
use warnings;
use feature 'say';
my @numbers = qw(
0.254
0.255
0.256
);
foreach my $number (@numbers) {
my $rounded = sprintf '%.2f', $number;
say "$number => $rounded";
}
foreach my $number (@numbers) {
$number += 100;
my $rounded = sprintf '%.2f', $number;
say "$number => $rounded";
}
Nó ra:
0.254 => 0.25
0.255 => 0.26
0.256 => 0.26
100.254 => 100.25
100.255 => 100.25
100.256 => 100.26
Đối với tôi nó là rất lạ rằng Perl là không phù hợp với làm tròn. Tôi hy vọng rằng cả hai số kết thúc với 0,255 để được làm tròn như 0,26 Nó đúng cho 0,255, nhưng nó là sai cho số 100,255
Dưới đây là trích dẫn từ Perl Cookbook http://docstore.mik.ua/orelly/perl/cookbook/ch02_04.htm
sprintf. Định dạng f cho phép bạn chỉ định một số thập phân cụ thể là số để làm tròn đối số của nó. Perl nhìn vào chữ số sau, làm tròn lên nếu số đó là 5 hoặc lớn hơn và làm tròn xuống theo cách khác.
Nhưng tôi không thể nhìn thấy bất kỳ bằng chứng cho thấy nó là chính xác trong http://perldoc.perl.org/functions/sprintf.html
Có một lỗi trong sprintf hoặc Perl Cookbook là sai? Nếu đó là hành vi mong muốn tại sao nó hoạt động theo cách này?
Dường như cũng ảnh hưởng đến '% g':' perl -E 'printf "% .3g \ n", 1.505'' cho 1,5, trong khi «perl -E' printf"% .3g \ n ", 1.506'' cho 1,51. Ngoài ra cả hai «perl -E 'printf"% .2g \ n ", 0,505'' và' perl -E' printf "% .2g \ n", 0,506'' cho 0,51 –
Bạn đang sử dụng hai số được làm tròn. Thay vào đó, hãy sử dụng 'say sprintf '% 1 $ .19g =>% 1 $ .2f', $ number;'. Điều này sẽ trả lời câu hỏi của bạn. – ikegami
Re "* Perl nhìn vào chữ số sau đây, làm tròn lên nếu nó là 5 hoặc lớn hơn, và làm tròn xuống nếu không. *", Điều này là không chính xác. Nó hoàn toàn dựa vào thư viện C cơ sở, mà có thể không nhất thiết phải sử dụng phương thức làm tròn đó. Trong thực tế, trên gcc xây dựng của tôi, nó làm tròn đến thậm chí.(Tuy nhiên, điều này không liên quan đến vấn đề của bạn.) – ikegami