我对带小数的整数有一个有趣的问题。
假设我执行以下操作:
[int] $a = 5/2
$a
我已经尝试了 10 次以确定,并且 powershell 总是返回2
在这种情况下,有没有办法强制 Powershell 向上或向下舍入,默认情况下它是否设置为向下舍入?
我假设取决于机器和 Powershell 环境,我可能会在某些时候获得 3 个,而在其他时候获得 2 个。
我对带小数的整数有一个有趣的问题。
假设我执行以下操作:
[int] $a = 5/2
$a
我已经尝试了 10 次以确定,并且 powershell 总是返回2
在这种情况下,有没有办法强制 Powershell 向上或向下舍入,默认情况下它是否设置为向下舍入?
我假设取决于机器和 Powershell 环境,我可能会在某些时候获得 3 个,而在其他时候获得 2 个。
[Math]::Floor($a) --> 2
[Math]::Ceiling($a)--> 3
[Math]::Round($a) --> 2
Floor
会给你前面的整数,Ceiling
并将提供后面的整数。但是,如果您想使用该Round
函数对其进行四舍五入,它将遵循中点舍入(中点舍入历史上远离零),如下所示 -
[Math]::Round(2.50) --> 2
[Math]::Round(2.51) --> 3
[Math]::Round(2.49) --> 2
[math]::Round(2.50,[System.MidpointRounding]::AwayFromZero) --> 3
[math]::Round(2.49,[System.MidpointRounding]::AwayFromZero) --> 2
[math]::Round(2.51,[System.MidpointRounding]::AwayFromZero) --> 3
您可以根据需要使用任一功能。
Vivek Kumar 的回答很有帮助,但有一些令人困惑的方面。
通常,将小数转换为整数总是涉及一种舍入形式;在强制转换和隐式转换的上下文中,编程语言通常使用一种舍入到最接近整数的形式。特殊考虑适用于小数部分正好是 的数字.5
的模棱两可的情况,存在不止一种策略- 并且不同的编程语言采用不同的策略。
在构建 PowerShell的.NET Framework的上下文中,这些策略的总称是midpoint rounding,下面使用的具体策略名称为简洁起见将 midpoint ( .5
) 称为half(下面的示例使用 PowerShell 语法,但适用于所有.NET 语言)。
转换为[int]
总是使用半到偶数舍入,其中小数部分的数字.5
被舍入到最接近的偶数(无论是正数还是负数):
[int] 2.5
-> 2
(!) 情景向下舍入,因为整数部分恰好是偶数和正数[int] 3.5
- >4
情境四舍五入/
,因此[int] 5/2
无法按预期工作;使用.[int] (5/2)
要控制中点舍入行为,请使用.NET[Math]
类的 Round()
方法:
用于[int] [Math]::Round($number, [MidpointRounding]::AwayFromZero)
从零舍入一半(带有小数的数字被舍入到绝对值较大的.5
最接近的整数)。
[Math]::Round(2.5, [MidpointRounding]::AwayFromZero)
->3
[Math]::Round(-2.5, [MidpointRounding]::AwayFromZero)
->-3
[Math]
方法(通常)返回 a [double]
,因此您可能必须将结果转换为[int]
(或不同的整数类型)才能获得真正的整数。请注意,[Math]::Round()
它不仅提供整数舍入,还提供特定数量的小数位数;例如,
[Math]::Round(2.55, 1, [MidpointRounding]::AwayFromZero)
产量2.6
。谢谢,Ansgar Wiechers。
其他形式的四舍五入:小数部分(除 以外0
)的具体值不相关的情况:
用于[Math]::Truncate($number)
接近零舍入(去除小数部分):
[Math]::Truncate(2.1)
-> 2
; 同上2.5
和2.9
,例如[Math]::Truncate(-2.1)
->-2
用于[Math]::Ceiling($number)
向正无穷舍入(向上舍入到最接近的大于或等于整数):
[Math]::Ceiling(2.1)
->3
[Math]::Ceiling(-2.1)
-> -2
(!)用于[int] [Math]::Floor($number)
向负无穷大舍入(向下舍入到最接近的较小或相等整数):
[Math]::Floor(2.1)
->2
[Math]::Floor(-2.1)
-> -3
(!)PowerShell 执行使用此策略的隐式转换的示例:
1..(2.5)
产生数组1, 2
,因为范围运算符表达式的端点2.5
, 被强制为[int]
2
,所以表达式实际上与1..2
由于 PowerShell 是在 .NET Framework 之上构建的,因此最终[Convert]::ToInt32()
会调用它。
根据维基百科的说法,可能令人惊讶的四舍五入策略背后的意图是“在对四舍五入的数字求和时最大限度地减少预期误差” 。
维基百科关于舍入的页面有一个关于跨编程语言的舍入函数的部分。
例如,与 .NET 相比,JavaScript采用了半向上舍入(Math.round(2.5)
-> 3
、Math.round(-2.5)
-> -2
)——一种 .NET 甚至不提供的中点舍入模式。