Подтвердить что ты не робот

Powershell - округляет до ближайшего целого числа

Какой лучший способ округлить до ближайшего целого числа в Powershell?

Я пытаюсь [math]:: truncate, но это не дает мне прогнозируемых результатов.

Пример:

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

выводит 171 вместо ожидаемых 172!

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

выходы 172

Просто нужно что-то, что работает... и должно всегда округлить (т.е. round($myNum + 0.5) не будет работать из-за округления заклинания, которое может округлить, если число имеет 0,5 компонента)

Отношения Ted

4b9b3361

Ответ 2

Функция Math:: Floor в сочетании с объявлением [decimal] должна дать вам нужные результаты.

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

возвращает = 172

Ответ 3

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

Ответ 4

[Math]::floor($x) - это встроенный способ сделать это.

Просто знайте, как он будет вести себя с отрицательными числами. [Math]::floor(5.5) возвращает 5, но [Math]::floor(-5.5) возвращает -6.

Если вам нужна функция, чтобы вернуть значение, самое близкое к нулю, вам понадобится:

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