2013-12-12 157 views
2

我不知道如果我在標題解釋清楚我的問題,基本上我需要一個樓/小區的功能是這樣的:如何四捨五入到Perl或任何語言的小數點左邊的第一位數字?

sub ceil($num) 

ceil(120) = 200 
ceil(12) = 20 
ceil(1.2) = 2 
ceil(0.12) = 0.2 
ceil(0.012) = 0.02 
ceil(0.00000012) = 0.0000002 

同樣適用於負數(負號的輸入和輸出)

謝謝!

+1

什麼[數學:: SigFigs(https://metacpan.org/pod/release/SBECK/Math-SigFigs-1.09/lib/Math/SigFigs 。莢)? – nwellnhof

+0

非常感謝。這似乎是我需要的。讓我試試 –

回答

3
sub floor { 
    my $a = shift; 
    $a =~ s/([1-9])(\d*)(?:\.\d*)?/$1.("0"x length($2))/e; 
    0 + $a; 
} 

sub ceil { 
    my $a = shift; 
    my $f = floor($a); 
    $f =~ s/([1-9])/1+$1/e if abs($a) > abs($f); 
    0 + $f; 
} 

和測試:

$ perl -E'sub floor {my $a = shift; $a=~s/([1-9])(\d*)(?:\.\d*)?/$1.("0"x length($2))/e; 0+$a} sub ceil {my $a = shift;my $f = floor($a); $f=~s/([1-9])/1+$1/e if abs($a) > abs($f); 0+$f} printf "%10g %10g %10g\n", $_, floor($_), ceil($_) for (120, 12, 1.2, 0.12, 0.012, 200, 20, 0.2, -120, -12, -0.12, -0.2,0, 1.2e12, -1.2e-12)' 
     120  100  200 
     12   10   20 
     1.2   1   2 
     0.12  0.1  0.2 
    0.012  0.01  0.02 
     200  200  200 
     20   20   20 
     0.2  0.2  0.2 
     -120  -100  -200 
     -12  -10  -20 
    -0.12  -0.1  -0.2 
     -0.2  -0.2  -0.2 
     0   0   0 
    1.2e+12  1e+12  2e+12 
    -1.2e-12  -1e-12  -2e-12 
+0

Hynek,這真的很酷。我從來沒有想過使用正則表達式來處理這類問題,因爲我一直認爲在數學問題的數學術語。非常感謝。 –

+0

如果你想要2^N四捨五入,你可以去位,但如果你需要10^N,除了十進制表示,即字符串以外,不存在這樣的數字表示。所以對我來說似乎很明顯。順便說一句,如果你需要2^N ceil:'static __inline unsigned clp2(unsigned x){return x> 1?(unsigned)INT32_MIN >>(__builtin_clz(x-1)-1):x; }} and floor'static __inline unsigned flp2(unsigned x){return 1 <<(sizeof(x)* 8-1 - __builtin_clz(x)); }用於C中的無符號數 –

1

這可能工作?我沒有測試過,但我認爲邏輯就在那裏。

步驟1,我們發現10個最近的電源(賦值給「$鹼基」)

步驟2中,我們確定是否$ num是一個乾淨divisble由該基地

步驟2.1,如果它是,返回

步驟2.2,如果不是的話,減去模,並添加1

$base = 10*floor(log($num,10)); 
return ($num % $base)?($num - ($num%$base) + 1):$num; 

數學是不是我的最強的東西,所以有可能是一個更好的方式去

+0

我剛剛意識到這不會爲小於1(IE:小數)的值工作,但它是一個開始。我會想辦法去適應這些。 – isick

+0

thx。我也考慮過採取日誌,但堅持小數以及 –

相關問題