Иллюстрированный самоучитель по Perl
Глава 1
Операции отношения
Для сравнения скалярных данных или
значений скалярных переменных язык Perl предлагает набор бинарных операций,
вычисляющих отношения равенства, больше, больше или равно и т. п. между своими
операндами, поэтому эту группу операций еще называют операциями отношения.
Для сравнения числовых данных и строковых данных Perl использует разные
операции. Все они представлены в табл. 4.1.
Таблица 4.1. Операции отношения
Операция |
Числовая
|
Строковая
|
Значение
|
Равенство
|
==
|
eq
|
Истина,
если операнды равны, иначе ложь |
Неравенство
|
!=
|
ne
|
Истина,
если операнды не равны, иначе ложь |
Меньше
|
<
| lt
|
Истина,
если левый операнд меньше правого, иначе ложь |
Больше
|
> |
gt
|
Истина,
если левый операнд больше правого, иначе ложь |
Меньше
или равно |
<=
| le
|
Истина,
если левый операнд больше правого или равен ему, иначе ложь |
Больше
или равно |
>= |
ge
|
Истина,
если правый операнд больше левого или равен ему, иначе ложь |
Сравнение
|
<=>
|
cmp
|
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
автоматически преобразует символьные данные в числовые там, где это необходимо.