Reputation: 477
I don't understand why this code doesn't work properly:
program selection;
var
n : integer;
begin
readln(n);
if (n in [100..1000]) then writeln('Selected!');
readln;
end.
this works fine for me with values between 1 and 233, if I enter 233, or more, the writeln.. doesn't get executed. This is very strange. I've also tried with other values, and the result is more or less the same, with only difference being the value it fails on.
Upvotes: 3
Views: 317
Reputation: 612993
Rob has explained why you cannot use Delphi sets for what you need. I would also stress that a set
is a very heavyweight type to store what amounts to an interval. Once this is recognised, it makes sense to use a function like InRange
which operates on intervals.
As a fun exercise, you can write a simple record that represents an interval. And then you can use operator overloading to implement an in
operator that will test for interval inclusion. This allows you to use the readable notation, and have the natural storage for an interval. And of course there are no constrains on element size.
Here is the simple demonstration:
{$APPTYPE CONSOLE}
type
TInterval = record
public
Low: Integer;
High: Integer;
public
class operator In(const Value: Integer;
const Interval: TInterval): Boolean; inline;
end;
class operator TInterval.In(const Value: Integer;
const Interval: TInterval): Boolean;
begin
Result := (Value>=Interval.Low) and (Value<=Interval.High);
// or implement with a call to Math.InRange()
end;
function Interval(Low, High: Integer): TInterval; inline;
begin
Result.Low := Low;
Result.High := High;
end;
begin
Writeln(25 in Interval(10, 100));
Writeln(125 in Interval(10, 100));
Writeln(2500 in Interval(1000, 10000));
Writeln(12500 in Interval(1000, 10000));
Readln;
end.
Upvotes: 7
Reputation: 163287
Delphi sets only go up to 255; a set with a maximum value of 1000 doesn't work. I'm a little surprised your code compiled.
When truncated to 8 bits, the value 1000 is 232, which explains why values larger than that fail.
Instead, you can use the InRange
function; it uses closed ranges just like set constructors.
if InRange(n, 100, 1000) then ...
You can also use plain old inequality operators to test whether the value lies in the given range:
if (100 <= n) and (n <= 1000) then ...
Finally, you can use a case
statement. Case-statement selectors aren't sets, so they're not subject to the same rules as sets.
case n of
100..1000: begin ... end;
end;
The downside is that it looks a little clumsy when there's only one case branch.
Upvotes: 13