PowerShell's range operator - ..
- generates an array of discrete values from the range endpoints, which can have the following types (in a given expression, both endpoints must have the same type):
[int]
(System.Int32
)
- e.g.,
1..3
creates array 1, 2, 3
- Note: While the minimum and maximum endpoint values allowed are
[int]::MinValue
and [int]::MaxValue
, respectively, the resulting array must additionally not have more than 2,146,435,071
elements (2+ billion), which is the max. element count for a single-dimensional [int]
array in .NET - see this answer for background information.
Alternatively, only in PowerShell [Core, 6+]: characters, which are enumerated between the endpoints by their underlying code points ("ASCII values").
- e.g.,
'a'..'c'
creates array [char] 'a', [char] 'b', [char] 'c'
Instances of numeric types other than [int]
are quietly coerced to the latter - if they can fit into the [int]
range - in which case half-to-even midpoint rounding is performed for non-integral types; e.g., implicit [double]
instances 23.5
and 24.5
are both coerced to 24
.
Because [int] 23.976
is 24
, your 23.976..60
expression creates array 24, 25, 26, ..., 60
which is not your intent.
In short: You cannot use ..
to describe an uncountable range of non-integers (fractional numbers).
Instead, use -ge
(greater than or equal) and -le
(less than or equal) to test against the endpoints:
-not ($value -ge 23.976 -and $value -le 60)
Additionally, in order to make the -ge
and -le
operations work as intended, convert the return value from Read-Host
, which is always a string, to a number.
If you were to use $value
as directly returned by Read-Host
, you'd get lexical (text sort order-based) comparison, not numeric comparison.
Therefore, cast the Read-Host
return value to [double]
:
$value = try { [double] (Read-Host 'Specify a value between 23.976 and 60') }
catch {}
Note: The try
/ catch
handles the case when the user enters text that cannot be interpreted as a [double]
representation.
To put it all together:
do {
$value = try { [double] (Read-Host 'Specify a value between 23.976 and 60') }
catch {}
} while (-not ($value -ge 23.976 -and $value -le 60))