Вот сценарий Perl:Почему Perl несовместим с округлением 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";
}
Он выводит:
0.254 => 0.25
0.255 => 0.26
0.256 => 0.26
100.254 => 100.25
100.255 => 100.25
100.256 => 100.26
Для меня это очень странно, что Perl не согласуется с округлением. Я ожидаю, что и номер заканчивается .255 быть закруглены +0,26 Это верно для 0,255, но это неверно для числа 100,255
Вот цитата из Perl Cookbook http://docstore.mik.ua/orelly/perl/cookbook/ch02_04.htm
Sprintf. Формат f позволяет указать определенное число десятичных мест для округления аргумента. Perl смотрит на следующую цифру: округляет до 5 или больше и округляет в противном случае.
Но я не вижу каких-либо доказательств того, что это правильно в http://perldoc.perl.org/functions/sprintf.html
Является ли это ошибка в Sprintf или Perl Cookbook это неправильно? Если это желательно, почему он работает таким образом?
Похоже также на '% g':' perl -E 'printf "% .3g \ n", 1.505'' дает 1.5, тогда как 'perl -E' printf"% .3g \ n ", 1.506'' дает 1.51. Также оба 'perl -E 'printf"% .2g \ n ", 0.505'' и' perl -E' printf "% .2g \ n", 0.506'' дают 0.51 –
Вы используете два округленных числа. Вместо этого используйте 'say sprintf '% 1 $ .19g =>% 1 $ .2f', $ number;'. Это ответит на ваш вопрос. – ikegami
Re "* Perl смотрит на следующую цифру, округляет, если она равна 5 или больше, и округляет в противном случае. *", Это неточно. Это полностью зависит от базовой библиотеки C, которая может не обязательно использовать этот метод округления. Фактически, на моей сборке gcc она округляется до четности.(Это не относится к вашей проблеме.) – ikegami