Powershell - 向下舍入到最接近的整数

ted*_*ted 25 powershell

在Powershell中舍入到最接近的整数的最佳方法是什么?

我正在尝试[math] :: truncate但它没有给我可预测的结果.

例:

$bla = 17.2/0.1
[math]::truncate($bla) 
Run Code Online (Sandbox Code Playgroud)

输出171而不是预期的172!

$bla = 172
[math]::truncate($bla) 
Run Code Online (Sandbox Code Playgroud)

输出172

只需要一些有效的东西....并且必须始终向下round($myNum + 0.5)舍入(即由于面包师的舍入而无法工作,如果数字为0.5,则可能会向上舍入)

关心泰德

Lou*_*uis 32

啊,我明白了.看起来数据类型需要是十进制的:

[decimal] $de = 17.2/.1
[double] $db = 17.2/.1

[math]::floor($de)
172
[math]::floor($db)
171
Run Code Online (Sandbox Code Playgroud)

http://msdn.microsoft.com/en-us/library/system.math.floor(v=vs.85).aspx


Tom*_*zel 22

Math :: Floor函数与[decimal]声明相结合可以为您提供所需的结果.

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

返回= 172

  • @Louis:因为浮点数不能精确地表示“ 17.2”和“ 0.1”,这就是为什么在最后几位会出现舍入误差,因此结果*接近*,但不是172的原因。 (2认同)

Emp*_*LII 9

您遇到原始17.2/0.1除法示例的问题是由于给定十进制值的浮点表示不准确(如Joey对另一个答案的评论中所述).您可以通过检查最终值的往返表示在PowerShell中看到这一点:

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

解决此问题的一种简单方法是将结果声明为int,因为PowerShell将自动舍入到结果为最接近的整数值:

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

请注意,这使用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
Run Code Online (Sandbox Code Playgroud)

另一种选择是使用更准确的原始值表示,这将完全避免问题:

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


Bac*_*its 5

[Math]::floor($x) 是内置的方法。

只要知道它在负数下的行为即可。 [Math]::floor(5.5)返回5,但[Math]::floor(-5.5)返回-6

如果您需要函数返回最接近零的值,则需要:

If ($x -ge 0) {
    [Math]::Floor($x)
} Else {
    [Math]::Ceiling($x)
}
Run Code Online (Sandbox Code Playgroud)

  • 要返回最接近零的值,可以使用`[Math] :: Truncate`。 (6认同)