2012-07-18 21 views
2

我想整理一個浮點數。例如,sprintf '%.4f', 0.12345返回0.1235sprintf '%.4f', 0.12325返回0.1232。對於第二個例子,我希望它打印出0.1233,而不是0.1232我如何收尾尾數爲5的浮動?

sprintf在Perl中不夠好。 Math::BigFloat可以做到這一點,但它有點過度殺傷。

有誰知道是否有其他有效的方法來整理,或者在Perl中是否有其他模塊?

+1

爲什麼你想在你的代碼中引入偏見?你不想讓4位數字產生地板,5位數字產生天花板,因爲這是不平衡的天花板。你需要4個去一個方向,4個去另一個方向,中間一個去觸發每隔一段時間。 Perl正是這樣做的。 – tchrist 2012-07-18 15:07:32

回答

0

該做的工作對我來說:

print sprintf '%.*f', 4, 0.12325 

您的代碼不工作對我來說太。你是否自己測試了這個代碼?
您能否告訴我們您的perl版本(perl -v)?

+0

有趣的是,你的解決方案和OP的'#2'爲我生成了相同的輸出結果:在32位WinXP機器上的Perl 5.12.4' MSWin32-x86-多線程Activeperl上運行'0.1233'。 – simbabque 2012-07-18 10:21:17

+0

對我來說,我編輯了我的答案。 Iam也使用'5.14.2' Activeperl MSWin32-x86-多線程。 – Brainbot 2012-07-18 10:25:48

+1

在Linux上,sprintf總是朝着最後5的方向發展。 – daxim 2012-07-18 10:34:37

1

確切的方式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

謝謝你的回答,但它仍然打印出0.1232,而不是我想要的 – amyxu 2012-07-19 01:55:07

+0

@amyxu,你嘗試了什麼?對於我提供的所有三個函數(0.12325,4)== 0.1233 – 2012-07-20 19:17:33