отрицательные числа и in

Вопросы программирования на Free Pascal, использования компилятора и утилит.

Модератор: Модераторы

Ответить
Аватара пользователя
Brainenjii
энтузиаст
Сообщения: 1351
Зарегистрирован: 10.05.2007 00:04:46

отрицательные числа и in

Сообщение Brainenjii »

часто пользуюсь конструкцией If x In [y..z] Then, а тут столкнулся со слабообъяснимой для меня ситуацией

Код: Выделить всё

Var
  i: Integer;
Begin
  i := 1;
  WriteLn(i in [1,-1, 200]); // TRUE
  i := -1;
  WriteLn(i in [1,-1, 200]); // FALSE?????!!!!oneone
  i := 200;
  WriteLn(i in [1,-1, 200]); // TRUE
End.

почему отрицательные значения не срабатывают?
Аватара пользователя
Максим
энтузиаст
Сообщения: 599
Зарегистрирован: 27.07.2007 01:51:43
Откуда: Москва

Сообщение Максим »

Выглядит, как кандидат на помещение в багтрекер.

Разместил там сообщение: http://bugs.freepascal.org/view.php?id=22915

P.S.
Ответ: множества ограничиваются байтовыми значениями, компилятор сыпет предупреждениями, поэтому ССЗБ. :mrgreen:
Последний раз редактировалось Максим 19.09.2012 16:58:17, всего редактировалось 1 раз.
Аватара пользователя
Brainenjii
энтузиаст
Сообщения: 1351
Зарегистрирован: 10.05.2007 00:04:46

Сообщение Brainenjii »

Ну вот, только собрался - а там уже и багрепорт и ответ на него висит - в наборах ([1, 2, ..]) можно использовать только byte значения. Более того, даже warning соответствующий генерируется. Я думал, что byte - это только к количеству элементов, ан нет...
Аватара пользователя
Vapaamies
постоялец
Сообщения: 292
Зарегистрирован: 24.07.2012 22:37:59
Откуда: Санкт-Петербург
Контактная информация:

Сообщение Vapaamies »

Хозяйке на заметку: когда мне нужно сделать подобные сравнения, а с <= и >= заморачиваться не хочется, использую case:

Код: Выделить всё

var
  I: Integer;
begin
  I := -1;
  case I of
    1,-1, 200:
      WriteLn(True);
  else
    WriteLn(False);
  end;
end;

Подглядывание в ассемблерный подстрочник показывает, что во многих случаях компилятор (Delphi) весьма эффективно вычисляет значения, а не сравнивает их втупую в лоб, поэтому способ крайне рекомендуется.
Аватара пользователя
Brainenjii
энтузиаст
Сообщения: 1351
Зарегистрирован: 10.05.2007 00:04:46

Сообщение Brainenjii »

но это 7 строчек вместо 2 *грустныйСмайлик*
Сквозняк
энтузиаст
Сообщения: 1159
Зарегистрирован: 29.06.2006 22:08:32

Сообщение Сквозняк »

Напиши модуль с несколькими функциями и сравнивай переменную A с числами в диапазоне INT64

Код: Выделить всё

if in_2(A,-1000,4)=true then ......
if in_3(A,-1000,4,9)=true then ......
if in_4(A,-1000,4,9,Q)=true then ......

Или с диапазонами таких чисел

Код: Выделить всё

if in_1d(A,-1000,4)=true then ......
if in_2d(A,-1000,4,Z,X)=true then ......
Аватара пользователя
Brainenjii
энтузиаст
Сообщения: 1351
Зарегистрирован: 10.05.2007 00:04:46

Сообщение Brainenjii »

Тогда уж так... Но тоже - это ещё модуль подключааааать :-D Но спасибо, так привык к этой фиче в языке, что про функции и не вспомнил ^_^

Код: Выделить всё

Function IsIn(Const aTarget: Integer; Const aValues: Array Of Integer): Boolean;
Var
  i: Integer;
Begin
  Result := FALSE;
  For i := Low(aValues) To High(aValues) Do
    If (aValues[i] === aTarget) Then
      Exit(TRUE);
End;
Сквозняк
энтузиаст
Сообщения: 1159
Зарегистрирован: 29.06.2006 22:08:32

Сообщение Сквозняк »

Это если для красоты, а для дела:

Код: Выделить всё

label
100;
begin
Result:=FALSE;
IF A<A1 THEN GOTO 100;
IF A>B1 THEN GOTO 100;
Result:=TRUE;
100:
end;
Ответить