我想整理一個浮點數。例如,sprintf '%.4f', 0.12345
返回0.1235
和sprintf '%.4f', 0.12325
返回0.1232
。對於第二個例子,我希望它打印出0.1233
,而不是0.1232
。我如何收尾尾數爲5的浮動?
sprintf
在Perl中不夠好。 Math::BigFloat
可以做到這一點,但它有點過度殺傷。
有誰知道是否有其他有效的方法來整理,或者在Perl中是否有其他模塊?
我想整理一個浮點數。例如,sprintf '%.4f', 0.12345
返回0.1235
和sprintf '%.4f', 0.12325
返回0.1232
。對於第二個例子,我希望它打印出0.1233
,而不是0.1232
。我如何收尾尾數爲5的浮動?
sprintf
在Perl中不夠好。 Math::BigFloat
可以做到這一點,但它有點過度殺傷。
有誰知道是否有其他有效的方法來整理,或者在Perl中是否有其他模塊?
該做的工作對我來說:
print sprintf '%.*f', 4, 0.12325
您的代碼不工作對我來說太。你是否自己測試了這個代碼?
您能否告訴我們您的perl版本(perl -v
)?
確切的方式sprintf
會舍入一個數字取決於系統庫如何舍入數字。如果您需要精確控制數字的舍入方式,則需要使用明確實現所需舍入的庫或編寫函數以根據需要進行舍入。
例如,將一個正數舍入到一個任意的精度,其中5舍入這個工作。
sub round {
my $numer = shift;
my $precision = shift;
return int($numer * 10 ** $precision + 0.5) * 10 ** -$precision;
}
但是,對於負數不能正確舍入,-0.12324錯誤地舍入到-0.1231。 5應該四捨五入(即朝向正無窮大)的解決方案是使用floor
而不是int
。
use POSIX qw(floor);
sub round {
my $numer = shift;
my $precision = shift;
return floor($numer * 10 ** $precision + 0.5) * 10 ** -$precision;
}
相反,如果5要圓的最大絕對值(即圓遠離0),那麼你可以添加爲負數圓他們在正確的方向上進行簡單的檢查。
sub round {
my $numer = shift;
my $precision = shift;
my $direction = $numer >= 0 ? 0.5 : -0.5;
return int($numer * 10 ** $precision + $direction) * 10 ** -$precision;
}
存在用於在某些情況下,其中從在一個方向上的所有數字四捨五入5的偏壓是不可接受的和浮點數的任何(十進制)的舍入取整所使用更復雜的規則被受到由於不精確性可能的錯誤以二進制格式。
謝謝你的回答,但它仍然打印出0.1232,而不是我想要的 – amyxu 2012-07-19 01:55:07
@amyxu,你嘗試了什麼?對於我提供的所有三個函數(0.12325,4)== 0.1233 – 2012-07-20 19:17:33
爲什麼你想在你的代碼中引入偏見?你不想讓4位數字產生地板,5位數字產生天花板,因爲這是不平衡的天花板。你需要4個去一個方向,4個去另一個方向,中間一個去觸發每隔一段時間。 Perl正是這樣做的。 – tchrist 2012-07-18 15:07:32