2011-05-03 124 views
21

在Powershell中舍入到最接近的整數的最佳方式是什麼?Powershell - 向下舍入到最接近的整數

我想[數學] :: truncate,但它沒有給我可預見的結果。

實施例:

$bla = 17.2/0.1 
[math]::truncate($bla) 

輸出171而不是預期的172!

$bla = 172 
[math]::truncate($bla) 

輸出172

只是需要一些工程....必須始終向下取整(即round($myNum + 0.5)不會因工作面包四捨五入可能圍捕如果數值0.5組件)

問候 特德

回答

17

的數學::樓函數[十進制]申報相結合應該給你你想要的結果。

[Math]::Floor([decimal](17.27975/0.1))

回報= 172

+0

輪輻太快...... [數學] ::地板(17.2/0.1)輸出171,我想這能輸出172 – ted 2011-05-03 00:49:28

+0

奇怪......這是爲什麼? – Louis 2011-05-03 01:01:48

+1

@Louis:因爲浮點數不能正好代表'17.2'和'0.1',這就是爲什麼你會在最後的位置得到舍入誤差,因此結果*接近*,但不完全是172. – Joey 2011-05-03 05:18:44

2

[Math]::floor($x)是內置的方式做到這一點。

只要意識到它將如何表現與負數。 [Math]::floor(5.5)返回5,但[Math]::floor(-5.5)返回-6

如果您需要的函數返回最接近零值,你將需要:

If ($x -ge 0) { 
    [Math]::Floor($x) 
} Else { 
    [Math]::Ceiling($x) 
} 
+2

要返回值最接近零,你可以使用'[Math] :: Truncate'。 – Joey 2011-05-03 05:21:52

7

您與原始17.2/0.1分割例遇到的問題是由於在給定的十進制值的浮點表示誤差(如前所述在另一個答案Joey's comment)。您可以通過檢查終值round-trip representation在PowerShell中看到這一點:

PS> $bla = 17.2/0.1 
PS> $bla.GetType().FullName 
System.Double 
PS> $bla.ToString() 
172 
PS> $bla.ToString('r') 
171.99999999999997 

一個簡單的方法來解決這個問題是要宣佈結果爲int,因爲PowerShell中會自動輪的結果爲最接近的整數值:

PS> [int]$bli = 17.2/0.1 
PS> $bli.GetType().FullName 
System.Int32 
PS> $bli.ToString() 
172 

注意,這裏使用的MidpointRounding.ToEven默認.NET方法(也被稱爲銀行家舍入)。這有製表大量數值的時候,但也可以改爲好的統計特性的簡單外之零點方法:

function round($value, [MidpointRounding]$mode = 'AwayFromZero') { 
    [Math]::Round($value, $mode) 
} 

PS> [int]3.5 
4 
PS> [int]4.5 
4 
PS> round 3.5 
4 
PS> round 4.5 
5 

另一種選擇是使用更準確地表述爲原始值,將完全避免這個問題:

PS> $bld = [decimal]17.2/0.1 
PS> $bld.GetType().FullName 
System.Decimal 
PS> $bld.ToString() 
172