2010-12-06 29 views
3

我討厭十進制數。對於1.005,我沒有得到我期望的結果與下面的代碼。在perl中舍入十進制數,錯誤結果

#!/usr/bin/perl -w 

use strict; 
use POSIX qw(floor); 

my $num = (1.005 * 100) + 0.5; 
print $num . "\n";   # 101 
print floor($num) . "\n"; # 100 
print int($num) . "\n";  # 100 

對於2.005和3.005它工作正常。

有了這個醜陋的「黑客」,我得到了預期的結果。

#!/usr/bin/perl -w 

use strict; 
use POSIX qw(floor); 

my $num = (1.005 * 100) + 0.5; 
$num = "$num"; 
print $num . "\n";   # 101 
print floor($num) . "\n"; # 101 
print int($num) . "\n";  # 101 

這樣做的正確方法是什麼?

+4

每位計算機科學家應該瞭解的浮點算術:http://docs.sun.com/source/806-3568/ncg_goldberg.html。 你可以嘗試使用整數對作爲有理數而不是這個。 – nlucaroni 2010-12-06 21:24:23

+2

實際上,您使用的是浮點數,而不是十進制數,因爲該術語通常在體系結構理論中定義。 – cdhowie 2010-12-06 21:24:29

回答

2

「正確」的方式來圓是任何方式選擇定義是正確的,你心裏有什麼目的。人們已經思考了很多,有些策略對於某些應用領域比其他策略更適合。

使用int()向零圓整很少有人想要的東西。通常他們想要一些數字上沒有偏見的東西。

公平分裂五個;因此速記術語「圓平等」。更接近的整數沒有定義:當最小siginficant數字是5時沒有接近整數。有9個事情,當取整時給出不同的答案:1,2,3,4,5,6,7,8 ,9。爲了公平起見,你們必須有一半走向另一半,一半走另一半。但有九個數字,所以你有四個走一個,四個走另一個,但現在你有一個公平的問題。因此避免偏見的唯一方法是讓5個案例上下交替。這就是爲什麼它以這種方式工作。

% perl -e 'printf "%.0f\n", $_+.5 for -10 .. +10' 

生產序列

-10 -8 -8 -6 -6 -4 -4 -2 -2 -0 0 2 2 4 4 6 6 8 8 10 10 

雖然這一輪,向零做法:

% perl -e 'print int($_+.5)," " for -10 .. +10; print "\n"' 

使這個在中間的駝峯:

-9 -8 -7 -6 -5 -4 -3 -2 -1 0 0 1 2 3 4 5 6 7 8 9 10 

展望再次回合:

% perl -le 'printf "%.1f ", $_+.05 for -10 .. +10' 

-9.9 -8.9 -8.0 -7.0 -6.0 -5.0 -4.0 -3.0 -1.9 -0.9 0.1 1.1 2.0 3.0 4.0 5.0 6.0 7.0 8.1 9.1 10.1 

如果你這樣做更有意義:

% perl -le 'printf "%.2f ", $_+.05 for -10 .. +10' 

-9.95 -8.95 -7.95 -6.95 -5.95 -4.95 -3.95 -2.95 -1.95 -0.95 0.05 1.05 2.05 3.05 4.05 5.05 6.05 7.05 8.05 9.05 10.05 

,然後再考慮什麼對,甚至指。