Проблема, с которой вы сталкиваетесь в исходном примере деления 17.2/0.1
, связана с неточностью в представлении с плавающей запятой заданных десятичных значений (как упомянуто в комментарии Джои к другому ответу).Это можно увидеть в 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
Обратите внимание, что при этом используется метод .NET по умолчанию MidpointRounding.ToEven (также известный как округление банкира).,Это имеет хорошие статистические свойства при табулировании большого числа числовых значений, но также может быть изменено на более простой метод от нуля:
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