为什么PowerShell中的整数比较是按位比较的?

15

我的代码告诉你你猜的数字是高于还是低于一个随机生成的数字,但当其中一个数字低于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)
例如,当$GeneratedNum = 56$Input = 7时,它返回"Too High"

3
Read-Host读取的值是字符串而不是整数。你的变量标记不是转换类型。在赋值语句右侧使用类型转换,似乎可以正确地工作。 - Etan Reisner
谢谢!那个完美地运行了。 - nick
4个回答

28

这是因为你正在将一个字符串与一个整数进行比较。顺序很重要。

"56" -lt 7

实际上与以下内容相同:

"56" -lt "7"

或者:

56 -lt "7"

会给你正确的结果。PowerShell 尝试将右侧参数强制转换为左侧参数的类型。

您可以尝试使用显式转换:

[int]$Input -lt $GeneratedNum

4
问题出在 Read-Host 返回的是一个字符串,所以通过你的强制转换,$Input 成为了一个 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)

你还应该使用 try{}catch{} 来捕获输入不是整数的情况。
你必须明白的是,当你使用PowerShell比较运算符时,左侧部分的类型被选定,因此右侧部分被转换为左侧类型。知道这一点,你可以编写以下代码,在比较运算符左侧放置一个整数变量$GeneratedNum
[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)

0

永远不要使用与自动变量相同的变量名:$input是一个自动变量。

看看这段代码,我从主机读取值并且没有使用$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)

需要注意的是,我的代码可以正确处理错误输入(非数字字符),例如w或字符串(qwerty),这使得其他方案失败。

我利用了您生成的整数始终大于0的事实。


0
使用 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)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接