Арифметические операции

Основное предназначение арифметических операций - выполнять определенные арифметические действия над числовыми данными: складывать, вычитать, умножать, делить и т. д. Это означает, что для арифметических операций все операнды вычисляются в числовом скалярном контексте. При этом строки, содержащие правильные числовые литералы, автоматически будут преобразованы в числовые значения: если строка не содержит правильного числового литерала, то интерпретатор попытается выделить из нее число, начиная с левого символа, и использовать его в качестве операнда; если не удается выделить правильный числовой литерал, то строковый операнд принимает нулевое значение.
Операции выполнения основных арифметических действий являются бинарными, так как для их выполнения требуется два операнда. Все, сказанное о преобразовании строк в числа, относится именно к таким операциям.
В языке определены также унарные арифметические операции: унарный плюс (+) и минус (-), а также операции автоматического увеличения (++) и уменьшения (--) значения операнда на единицу. Для операндов таких операций создается скалярный контекст, но результаты их выполнения для числовых и скалярных величин определяются совершенно разными алгоритмами.

Бинарные арифметические операции

В языке определено шесть бинарных арифметических операций, которые представлены в табл. 4.1.
Таблица 4.1. Бинарные арифметические операции
Операция Знак Пример Результат
Сложение + 3.14+123;
"3.14"+"123";
"3.14"+123;
126.14
126.14
126.14
Вычитание - 3.14-123;
"3.14"-"123";
"3.14"-123;
-119.86
-119.86
-119.86
Умножение * 3.14*123;
"3.14"*"123";
"3.14"*123;
"31"*12;
386.22
386.22
386.22
372
Деление / 3.14/123;
"3.14"/"123";
"3.14"/123;
"31"/12
0.0255284552845528
0.0255284552845528
0.0255284552845528
2.58333333333333
Остаток от деления целых чисел % 127%123;
"127"%123;
"127.58"%"123";
"127.58"%123.98;
4
4
4
4
Возведение в степень ** 2.5**3;
"-2.5"**3;
"+2.5"**"-3";
"-2.5"**(-3);
2.5**(-3,01)
15.625
-15.625
0.064
-0.064
0.0634162524282757
Операции для четырех основных арифметических действий — сложения, вычитания, умножения и деления — истребуют комментария. Они выполняются аналогично тому, как это принято в математике, с учетом преобразования значений строковых операндов в числа, причем все вычисления осуществляются с двойной точностью, если один из операндов представлен вещественным числом. Две бинарные арифметические операции — остаток от деления и возведение в степень — требуют некоторого пояснения.
ВНИМАНИЕ. В Perl основные арифметические операции внутренне вычисляются с двойной точностью, если хотя бы один из операндов представлен вещественным числом.
Операндами операции получения остатка должны быть целые числа. Поэтому вещественные значения преобразуются к целым простым отбрасыванием дробной части, что и демонстрирует последний пример в табл. 4.1.
Операция возведения в степень выполняет возведение в любую (положительную или отрицательную, целую или вещественную) степень любого положительного числа. Отрицательные числа можно возводить только в целую (положительную или отрицательную) степень. При попытке возвести отрицательное число в вещественную степень, результат непредсказуем, а интерпретатор не отобразит никаких предупреждающих сообщений, например на моем компьютере результат выполнения подобной операции выглядит так:
$m = (-2.5)**(3.01); # Переменная $m содержит -2147483648
Как отмечалось ранее, в бинарных арифметических операциях Perl позволяет использовать строки, не содержащие правильные числовые литералы. В этом случае интерпретатор попытается выделить, начиная с первого символа, из содержимого строки число и использовать его в качестве соответствующего операнда заданной операции. Если не удается выделить правильный числовой литерал, то операнд принимает значение, равное 0. Продемонстрируем использование строковых операндов:
 
"3fl4" + "12-30"; (результат: 15 (3+12));
"а120" - "12-30"; (результат: -12 (0 - 12)); 
"а120" * "-0012-30"; (результат: 0) (0 * (-12)).
ПРИМЕЧАНИЕ Если установить режим отображения предупреждающих сообщений интерпретатора (опция -w), то при попытке использовать в бинарной арифметической операции строку, не содержащую правильный числовой литера, будет отображено сообщение вида:
Argument "12-30" isn’t numeric in addition(+) at ex04-01.pl line 10/
Арифметические операции «создают» скалярный контекст для своих операндов. Однако мы знаем, что в скалярном контексте можно использовать не только скалярные величины и переменные, но и массивы Perl. Поэтому в качестве операндов арифметических бинарных операций можно использовать и массивы. В этом случае следует учитывать значение, возвращаемое массивом в скалярном контексте: для массива скаляров это количество его элементов, а для хэш-массива — строка, содержащая количество использованных и количество выделенных записей в хэш-таблице, разделенных наклонной чертой, которая, в конечном итоге, преобразуется в количество выделенных записей. Примеры массивов в арифметических операциях:
@m = (1, 3, 5, 7, 9, 11);
%m1 = ( city => "Paris", river => "Seinne");
$n = 10;
print $n + @m, "\n";   # Результат; 16 (10 + 6);
print @m + %m1, "\n";  # Результат: 6 (5 + 1).
При выполнении этого фрагмента для размещения хэш-массива была использована одна запись из восьми выделенных, поэтому в скалярном числовом контексте значением хэш-массива будет 1. Эту информацию можно получить из отображаемого интерпретатором perl предупреждающего сообщения:
Argument "1/8" isn't numeric in addition (+) at ex04-01.pl line 6.

Унарные арифметические операции

В Perl существуют две унарные арифметические операции — «плюс» (+) и «минус» (-), которые применяются к любым скалярным значениям.
Арифметическая операция «унарный плюс» (+) не оказывает никакого эффекта ни на числовое, ни на строковое значение. Единственный случай, где она необходима (правда, здесь она уже не является арифметической операцией), — это перед первым параметром списковой операции, если он представлен выражением в круглых скобках. Здесь она нужна, чтобы указать компилятору, что это всего лишь первый передаваемый параметр из целого списка, а не единственный параметр этой операции.
«Унарный минус» (-) выполняет арифметическое отрицание числового операнда. Это означает, что если число было отрицательным, то оно станет положительным, и наоборот. Если операндом является идентификатор, то результатом выполнения этой операции будет строка, состоящая из символа -, за которым следует идентификатор, то есть если в тексте программы встречается, например, выражение -word, то результатом выполнения операции унарного минуса в атом случае будет строка "-word". Если операндом является строка, начинающаяся с символа минус или плюс, то результатом также будет строка, в которой минус заменен на плюс и наоборот. Если строка не начинается с плюса или минуса, операция унарного минуса добавляет его первым символом в строку. Перечислим случаи использования операции унарного минуса:
print -'12.09', "\n";  # результат: -12.09;
print -(-12.09), "\n"; # результат: 12.09;
print –id, "\n";       # результат: '-id';
print -'+id', "\n";    # результат: '-id';
print -"-id", "\n";    # результат: "+id";
print -'al20', "\n";   # результат: '-а120'.
Применение операции «унарный минус» к массивам:
@m = (1, 3, 5, 7, 9, 11);
%m1 = ( city => "Paris", river => "Seinne");
print -@m, "\n"; # Результат:  -6
print -%m1, "\n"; # Результат:  -1

Операции увеличения и уменьшения

Синтаксис и семантика операций увеличения (++) и уменьшения (--) на единицу в Perl полностью соответствуют аналогичным операциям языка С — они соответственно увеличивают или уменьшают на единицу значение своего операнда. Существует две формы этих операций: префиксная, когда знак операции стоит перед операндом, и постфиксная — знак операции ставится после операнда; эти формы отличаются семантикой использования. Префиксные операции увеличения и уменьшения сначала соответственно увеличивают или уменьшают значение своего операнда, а потом используют его в вычислениях. Постфиксные формы этих операций, наоборот, сначала используют в выражениях значения своих операндов, а потом увеличивают или уменьшают их значения на единицу. Так как операции увеличения/уменьшения выполняют также и операцию присваивания своему операнду нового значения, то в качестве операнда может использоваться только скалярная переменная. Причем если она содержит строку, то ее содержимое преобразуется к числовому значению в соответствии с алгоритмом, описанным в начале главы, а потом уже выполняется сама операция. Если из строкового содержимого переменной не удается выделить числовое значение, то оно полагается равным нулю, за исключением случаев, о которых речь пойдет ниже. Рассмотрим случаи использования операций увеличения/уменьшения на единицу с числовыми операндами и строковыми операндами, преобразуемыми к числовым значениям:
$n = 10.7;         — начальное значение
$inf1 = --$n;      — результат: $inf1 = 9.7, $n = 9.7; 
$inf2 = ++$n;      — результат: $inf2 = 10.7, $n = 10.7;
$post1 = $n--;     — результат: $post1 = 10.7, $n = 9.7;
$post2 = $n++;     — результат: $post2 = 9.7,$n = 10,7;
$n = "10.7cm";     — начальное значение
$inf1 = --$n;      — результат: $inf1 = 9.7, $n = 9.7;
$post2 = $n++;     — результат: $post2 = 9.7, $n = 10.7; 
$n = "h = 10.7cm"; — начальное значение
$post1 = $n++;     — результат: $post1 = "h = 10.7cm", $n = 1
$n = "h = 10.7cm"; — начальное значение
$inf1 = ++$n;      — результат: $inf1 = 1, $n = 1.
Обратите внимание на постфиксную операцию увеличения, когда она применяется к переменной, из содержимого которой не удается выделить числовое значение (предпоследняя операция увеличения на единицу из приведенного выше примера). Переменная $post1 содержит первоначальное содержимое переменной $n, тогда как сама переменная $n содержит уже 1. В случае с префиксной формой операции увеличения обе переменные после выполнения операции присваивания содержат числовое значение 1.
Операция увеличения ++, примененная к переменной, содержащей строки определенного вида, выполняется несколько необычно. Эта операция, как отмечается в документации, в данном случае обладает встроенным «волшебством».
Если строка состоит только из латинских букв, то возвращаемым значением операции увеличения будет строка, в которой последняя буква заменена на следующую но порядку букву алфавита, причем строчная заменяется строчной, а прописная прописной. Если строка завершается идущими подряд буквами z или Z, то все они заменяются соответственно на а или А, а стоящая перед ними в строке буква заменяется на следующую по порядку букву алфавита. Если вся строка состоит из букв z и Z, то кроме замены этих букв в соответствии с предыдущим правилом перед ними добавляется строчная или прописная буква а в зависимости от того, строчная или прописная буква z стояла первой в строке.
Аналогичные действия осуществляются, если строка завершается последовательностью цифр: последняя цифра увеличивается на единицу. Если строка завершается идущими подряд цифрами 9, то все они заменяются на 0, а примыкающий к ним символ «увеличивается» на единицу: буква переходит в символ следующей по алфавиту буквы, а цифра — в следующую по порядку цифру. Если последовательность целиком состоит из девяток, то все они заменяются на нули, перед которыми добавляется единица. Ниже приведены некоторые случаи применения операции увеличения ++ к указанным строкам.
$s = "abc";
$s1 = ++$s; — результат: $s1 = "abd"
$s = "abC";
$s1 = ++$s; — результат: $s1 = "abD"
$s = "abz";
$s1 = ++$s; — результат: $s1 = "аса"
$s = "abzZz";
$s1 = ++$s; — результат: $s1 = "acaAa"
$s = "аbО9";
$s1 = ++$s; — результат: $s1 = "аb1О"
$s = "a99";
$s1 = ++$s; — результат: $s1 = "b00"
ВНИМАНИЕ Операция уменьшения — таким свойством не обладает и работает со всеми строками одинаково.

Следующая страница Содержание главы


Реклама