Reputation: 21
What exactly am I doing wrong here, it seems to be subtracting just fine but adding and multiplying seems to not work at all.
How do I get it to do the calculations correct and allow the if statement to also work as it seems to always run even if the numbers are incorrect size.
$a = Read-Host "What is your name?"
$b = Read-Host "Enter a 2 digit number"
$c = Read-Host "Enter a 3 digit number"
if (($b -ge 10) -and ($b -le 99) -and ($c -ge 100) -and ($c -le 999)){
$d = $b + $c
$e = $b * $c
$g = $b - $c
$d
$e
$g
Write-host "Here you go $a"
}
else {
write-host "Enter the numbers correctly"
}
Upvotes: 2
Views: 286
Reputation: 437042
Read-Host
always outputs a string.
In order to treat its output - or any string - as a number, you must explicitly convert it to one:
$a = Read-Host "What is your name?"
# Note: Add error handling with try / catch
# and a retry loop to deal with invalid input.
[int] $b = Read-Host "Enter a 2 digit number"
[int] $c = Read-Host "Enter a 3 digit number"
The above type-constrains variables $b
and $c
to integer values (by placing the [int]
cast to the left of the target variable in the assignment), which automatically converts Read-Host
's [string]
output to [int]
.
This also works ad hoc with casts: [int] '2' -lt 10
is $true
(without the [int]
cast, due to lexical comparison, it would be $false
).
To spell it out with a concrete example that prompts until a two-digit (decimal) number is entered:
do {
try {
[int] $b = Read-Host "Enter a 2 digit number"
} catch {
continue # Not a number - stay in the loop to prompt again.
}
if ($b -ge 10 -and $b -le 99) { break } # OK, exit the loop.
} while ($true)
Note: Strictly speaking, the [int]
cast accepts anything that would work as a number literal in PowerShell, which includes hexadecimal representations, such as 0xA
, as well as number with a type suffix, such as 10l
- see this answer for more information.
As for what you tried:
Except for -
(and /
), all the operators used in your code have string-specific overloads (meaning); note that it is sufficient for the LHS to be of type [string]
to trigger this behavior.[1]
-lt
/ -ge
perform lexical comparison with strings; e.g., '10' -gt '2'
yields $false
, because, in lexical sorting, string '10'
comes before string '2'
.
-and
/ -or
treat empty strings as $false
, and any nonempty string as $true
; e.g., '0' -and '0'
is $true
, because '0'
is a nonempty string.
+
performs string concatenation; e.g., '1' + '0'
is '10'
.
*
performs string replication; e.g., '1' * 3
is '111'
- the LHS is repeated as many times as specified by the number on the RHS; note that '1' * '3'
works the same, because the RHS is coerced to an [int]
in this case.
-
and /
are the only exceptions: they always perform a numeric operation, if possible; e.g, '10' - '2'
yields 8
, and '10' / '2'
yields 5
, because both operands were implicitly converted to [int]
s.
[1] Typically, it is the LHS of an operation that determines the data type of both operands, causing the RHS to be coerced to the same type, if necessary.
Upvotes: 3