powershell comparison operators

¿Por qué los enteros en PowerShell se comparan por dígitos?



comparison operators (4)

Mi código le dice si su número adivinado es mayor o menor que un número generado aleatoriamente, pero parece que solo compara los primeros dígitos del número cuando uno de ellos está por debajo de 10.

[int]$GeneratedNum = Get-Random -min 1 -max 101 Write-Debug $GeneratedNum $isQuitting = $false Do{ [int]$Input = Read-Host "Take a guess!" If($Input -lt $GeneratedNum){Write-Output "Too Low"} If($Input -gt $GeneratedNum){Write-Output "Too High"} If($Input -eq $GeneratedNum){Write-Output "Good Job!"; $isQuitting = $true} } Until($isQuitting -eq $true)

Por ejemplo, cuando $GeneratedNum = 56 y $Input = 7 , devuelve "Too High"


El problema proviene del hecho de que Read-Host devuelve una cadena, por lo que con su conversión $Input es un intento ArrayListEnumeratorSimple :

[int]$GeneratedNum = Get-Random -min 1 -max 101 Write-host $GeneratedNum $isQuitting = $false Do{ $Input = (Read-Host "Take a guess!") -as [int] If($Input -lt $GeneratedNum){Write-Output "Too Low"} If($Input -gt $GeneratedNum){Write-Output "Too High"} If($Input -eq $GeneratedNum){Write-Output "Good Job!"; $isQuitting = $true} } Until($isQuitting -eq $true)

También debe usar try{}catch{} para detectar el caso de que la entrada no sea un int.

Lo que debe entender es que cuando usa operadores de comparación de PowerShell, el tipo de la parte izquierda se usa seleccionado, por lo que la parte derecha se convierte en el tipo izquierdo. Sabiendo que podría haber escrito lo siguiente, donde acabo de poner el $GeneratedNum que es un número entero a la izquierda de las comparaciones:

[int]$GeneratedNum = Get-Random -min 1 -max 101 Write-host $GeneratedNum $isQuitting = $false Do{ $Input = (Read-Host "Take a guess!") If($GeneratedNum -gt $Input){Write-Output "Too Low"} If($GeneratedNum -lt $Input){Write-Output "Too High"} If($GeneratedNum -eq $Input){Write-Output "Good Job!"; $isQuitting = $true} } Until($isQuitting -eq $true)


Esto se debe a que estás comparando una cadena con un número entero. El orden importa.

"56" -lt 7

En realidad es lo mismo que:

"56" -lt "7"

Alternativamente:

56 -lt "7"

te daría el resultado correcto. PowerShell intenta forzar el argumento del lado derecho al tipo del lado izquierdo.

Puede intentar un reparto explícito:

[int]$Input -lt $GeneratedNum


Nunca use una variable con el mismo nombre que una variable automática: $input es una variable automática.

Vea este código, donde canalizo el valor leído desde el host (y no uso la variable $input ):

[int]$GeneratedNum = Get-Random -min 1 -max 101 Write-Debug $GeneratedNum $isQuitting = $false Do{ Read-Host "Take a new guess!" | %{ if($_ -as [int] -gt 0){ If($_ -lt $GeneratedNum){Write-Output "Too Low"} If($_ -gt $GeneratedNum){Write-Output "Too High"} If($_ -eq $GeneratedNum){Write-Output "Good Job!"; $isQuitting = $true} } } } Until($isQuitting -eq $true)

Es importante tener en cuenta que mi código trata correctamente las entradas incorrectas (caracteres no numéricos) como w o como cadenas ( qwerty ), lo que hace que las otras propuestas fallen.

Aprovecho el hecho de que usted genera enteros siempre mayores que 0.


Usando un switch :

[int]$GeneratedNum = Get-Random -min 1 -max 101 Write-Debug $GeneratedNum :lop Do{ switch ((Read-Host ''Take a new guess!'') -as [int]) { {$_ -eq $null}{continue} {$_ -lt $GeneratedNum}{''Too Low'';continue} {$_ -gt $GeneratedNum}{''Too High'';continue} {$true}{''Good Job!'';break lop} } } while($true)