Изучаем Java

Вы здесь: Главная >> Java-учебник >> Операторы

Операторы в языке Java



Для обозначения операций сложения, вычитания, умножения и деления в языке Java используются обычные арифметические операторы + - * /.

Оператор / обо­значает целочисленное деление, если оба его аргумента являются целыми числами. В противном случае этот оператор обозначает деление чисел с плавающей точкой. Остаток от деления целых чисел (т.е. функция mod) обозначается символом %.
На­пример, 15/2 равно 7, 15%2 равно 1, а 15 . 0/2 равно 7 . 5.

Заметим, что целочисленное деление на 0 возбуждает исключительную ситуацию, в то время как результатом деления на 0 чисел с плавающей точкой является беско­нечность или NaN.

Арифметические операторы можно использовать для инициализации переменных.

int n = 5;
int а = 2 * n; // Значение переменной а равно 10.

В операторах присваивания удобно использовать сокращенные бинарные ариф­метические операторы.

Например, оператор
х + = 4;
эквивалентен оператору
х = х + • 4;

(Сокращенные операторы присваивания образуются путем приписывания символа арифметической операции, например * или %, перед символом =, например *=или %=.)

Одной из заявленных целей языка Java является машинная независимость.

Вы­числения должны приводить к одинаковому результату, независимо от того, какая виртуальная машина их выполняет. Для арифметических вычислений над числами с плавающей точкой это неожиданно оказалось трудной задачей. Тип double для хранения числовых значений использует 64 бит, однако некоторые процессоры применяют 80-разрядные регистры с плавающей точкой. Эти регистры обеспечи­вают дополнительную точность на промежуточных этапах вычисления, Рассмот­рим в качестве примера следующее выражение:

double w = х * у / z;

Многие процессоры компании Intel вычисляют выражение х * у и сохраняют этот промежуточный результат в 80-разрядном регистре, затем делят его на значение переменной z и в самом конце округляют ответ до 64 бит. Так можно повысить точ­ность вычислений, избежав переполнения. Однако этот результат может оказаться иным, если в процессе всех вычислений используется 64-разрядный процессор.

По этой причине в первоначальном описании виртуальной машины Java указывалось, что все промежуточные вычисления должны округляться. Это возмутило компью­терное сообщество. Переполнение могут вызвать не только округленные вычисле­ния. На самом деле они выполняются медленнее, чем более точные вычисления, поскольку операции округления занимают определенное время. В результате раз­работчики языка Java изменили свое мнение, стремясь разрешить конфликт между оптимальной производительностью и отличной воспроизводимостью результатов.

По умолчанию разработчики виртуальной машины теперь позволяют использовать расширенную точность в промежуточных вычислениях. Однако методы, помеченные ключевым словом strictfp,должны использовать точные операции над числами с плавающей точкой, что гарантирует воспроизводимость результатов. Например, метод main можно пометить ключевыми словами, как показано ниже:
public static strictfp void main(String[] args)

В этом случае все команды внутри метода main будут выполнять точные операции над числами с плавающей точкой.

Детали выполнения этих операций тесно связаны с особенностями работы про­цессоров Intel. По умолчанию промежуточные результаты могут использовать расширенный показатель, но не расширенную мантиссу. (Микросхемы компании Intel поддерживают округление мантиссы без потери производительности.) Сле­довательно, единственное различие между вычислениями по умолчанию и точны­ми вычислениями состоит в том, что точные вычисления могут приводить к пере­полнению, а вычисления по умолчанию — нет.

Если при чтении этого замечания ваш взгляд потускнел, не волнуйтесь. Для боль­шинства программистов этот вопрос совершенно не важен. Переполнение при вычислениях чисел с плавающей точкой в большинстве случаев не возникает. В этой книге мы не будем использовать ключевое слово strictfp.

Операторы инкрементации и декрементации

Программисты, конечно, знают, что одной из наиболее распространенных опера­ций с числовыми переменными является добавление или вычитание единицы. В язы­ке Java, как и в языках С и C++, есть операторы инкрементации и декрементации: оператор х++ добавляет единицу к текущему значению переменной х, а оператор х- - вычитает из него единицу.

Например, код
int n = 12;
n++;
делает значение переменной n равным 13.

Поскольку эти операторы изменяют зна­чение переменной, их нельзя применять к самим числам. Например, оператор 4++ является недопустимым.

Существует два вида этих операторов. Выше показана "постфиксная" форма опе­ратора, в которой символы операции размещаются после операнда. Есть и "префиксная" форма— ++n.
Оба этих оператора увеличивают значение переменной на единицу. Разница между ними проявляется, только когда эти операторы использу­ются внутри выражений. Префиксная форма оператора инкрементации сначала до­бавляет единицу к значению переменной, в то время как постфиксная форма исполь­зует старое значение этой переменной.

int m = 7;
int n = 7;
int а = 2 * ++m; // Теперь значение а равно 16, a m — 8.
int b = 2 * n++; // Теперь значение b равно 14, a n — 8.

Мы не рекомендуем использовать оператор инкрементации ++ внутри выраже­ний, поскольку это зачастую приводит к запутанному коду и досадным ошибкам.

(Поскольку именно оператор ++ дал имя языку C++, это послужило поводом к пер­вой шутке о нем. Недоброжелатели указывают, что даже имя этого языка содержит в себе ошибку: "Кроме всего прочего, этот язык следовало бы назвать ++С, потому что мы хотим использовать этот язык только после его улучшения".)


Партнеры сайта