Для сравнения скалярных данных или значений скалярных
переменных язык Perl предлагает набор бинарных операций, вычисляющих
отношения равенства, больше, больше или равно и т. п. между
своими операндами, поэтому эту группу операций еще называют
операциями отношения. Для сравнения числовых данных и строковых
данных Perl использует разные операции. Все они представлены
в табл. 4.1.
Таблица 4.1. Операции отношения
Операция |
Числовая |
Строковая
|
Значение
|
Равенство
|
== |
eq |
Истина, если
операнды равны, иначе ложь |
Неравенство |
!= |
ne |
Истина, если
операнды не равны, иначе ложь |
Меньше
|
< |
lt |
Истина, если
левый операнд меньше правого, иначе ложь |
Больше
|
> |
gt |
Истина, если
левый операнд больше правого, иначе ложь |
Меньше
или равно |
<= |
le |
Истина, если
левый операнд больше правого или равен ему, иначе ложь
|
Больше
или равно |
>= |
ge |
Истина, если
правый операнд больше левого или равен ему, иначе ложь
|
Сравнение
|
<=> |
cmt |
0, если операнды
равны
1, если левый операнд больше правого
-1, если правый операнд больше левого |
Результатом операций
отношения (кроме последней сравнения) является Истина, значение
1, или Ложь, пустая строка "".
Замечание
Значение истина в арифметических операциях интерпретируется
как число 1, а в строковых как строка "1". Значение
ложь в арифметических операциях интерпретируется как число
0, а в строковых как пустая строка " ".
Числовые операции отношения
Числовые операции
отношения применяются к числовым данным, причем один или оба
операнда могут задаваться строкой, содержащей правильное десятичное
число. Если в числовых операциях отношения какой-либо из операндов
задан строкой, содержимое которой не представляет правильное
десятичное число, то его значение принимается равным о и отображается
предупреждение о некорректном использовании операнда в числовой
операции отношения (если включен режим отображения предупреждений
интерпретатора Perl). Смысл операций отношения для числовых
данных соответствует обычным математическим операциям сравнения
чисел (пример 4.7).
123 > 89; # Результат: 1 (истина)
123 < 89; # Результат: "" (ложь)
123 <= 89; # Результат: "" (ложь)
89 <= 89; # Результат: 1 (истина)
23 >= 89; # Результат: "" (ложь)
23 <=> 89; # Результат: -1 (правый операнд больше левого)
89 <=> 23; # Результат: 1 (правый операнд больше левого)
Применение числовых операций
сравнения не представляет сложности, однако при сравнении
на равенство десятичных чисел с плавающей точкой могут проявиться
эффекты округления, связанные с ограниченным количеством значащих
цифр в мантиссе представления действительных чисел в компьютере
и приводящие к "неправильной", с точки зрения пользователя
работе операций сравнения. Пример 4.8 иллюстрирует подобную
ситуацию.
#! peri -w
$z = 0.7;
$zz =• 10+0.7-10; # Переменная $zz содержит число 0.7
# Печать строки "z равно zz", если равны значения
переменных $z и $zz print "z равно zz\n" if ($z
== $zz);
При попытке выполнить пример
4.8 мы с удивлением обнаружим, что наша программа ничего не
напечатает. В чем же дело? Разгадка лежит в операторе вычисления
значения переменной $zz. При выполнении арифметических операций
в результате ошибок округления получается значение 0.699999999999999
(можете вставить оператор печати переменной $zz и убедиться
в этом), хотя и близкое к 0.7, но не равное ему в точности.
Следовательно, операция сравнения отработала верно!
Совет
Не используйте операцию сравнения на равенство вещественных
чисел, ее результат может не соответствовать ожидаемому с
точки зрения математики. Если необходимо проверить равенство
двух вещественных чисел, то лучше сравнивать абсолютное значение
их разности с некоторым очень маленьким числом (в зависимости
от требуемой точности):
abs($a-$b) <= 0.00000001; # Проверка равенства
Строковые операции отношения
Сравнение строковых
данных базируется на их упорядочении в соответствии с таблицей
кодов ASCII, т. е. символ с меньшим кодом ASCII предшествует
символу с большим кодом. Сравнение строк осуществляется посимвольно
слева направо. Это означает, что если равны первые символы
строк, то сравниваются вторые и если они равны, то сравниваются
третьи и т. д. Причем, если строки разной длины, то в конец
строки меньшей длины добавляется недостающее для равенства
количество символов с кодом о. Следует отметить, что в отличие
от некоторых других языков программирования в Perl замыкающие
строку пробельные символы являются значимыми при сравнении
строк. В примере 4.9 показаны сравнения строк, иллюстрирующие
изложенные правила.
"A"
It "a"; |
#
Результат: истина (код "А" - \101, код "а"
- \141) |
"a"
It "aa"; |
# Результат:
истина (к строке "а" добавляется символ
# с кодом \000, который меньше кода \141
# второго символа "а" строки правого операнда)
|
"a"
It "a "; |
# Результат:
истина (к строке "а" добавляется символ
# с кодом \000, который меньше кода \040
# замыкающего пробела строки правого операнда) |
"12"
It "9"; |
# Результат:
истина (код "1" - \061, код "9" -
\071) |
"9"
eq 09"; |
# Результат:
ложь (код " " - \040, код "О" - \060)
|
Обратим внимание
на две последние операции сравнения строковых литералов. Содержимое
их операндов может быть преобразовано в правильные числа,
и поэтому к ним применимы аналогичные числовые операции отношения.
Однако их результат будет существенно отличаться от результата
выполнения строковых операций отношения. При использовании
операции < в предпоследнем выражении результат будет Ложь,
а если в последнем выражении применить операцию ==, то результат
будет Истина. Об этом всегда следует помнить, так как Perl
автоматически преобразует символьные данные в числовые там,
где это необходимо. |