Тип boolean и операторы сравнения в java
Содержание:
Общий синтаксис
Учитывая эти примеры, видно, что общий синтаксис выглядит следующим образом:
result = testCondition ? value1 : value2
Как описано в Oracle documentation, логика применения состоит в том, что «Если testCondition имеет значение true, присвойте значение value1 результату; в противном случае присвойте значение value2 результату».
Вот еще два примера, которые демонстрируют это очень ясно. Вот пример использования значения с плавающей запятой:
// результату присваивается значение 1.0 float result = true ? 1.0f : 2.0f
Использования String:
// результату присваивается значение «Извини, чувак, это ложь».
String result = false ? "Dude, that was true" : "Sorry Dude, it's false";
testCondition может быть либо простым логическим значением, либо может быть оператором, который оценивает логическое значение, как оператор (a<0), показанный ранее.
Еще один пример, который я видел в исходном коде проекта под названием Abbot:
private static final int subMenuDelay = Platform.isOSX() ? 100 : 0;
Конструкция «IF (COND) THEN Statement (s) ELSE Statement (s)» сама по себе является выражением.
«COND ? Statement : Statement» является выражением, и, следовательно, может находиться справа от присваивания.
Можно использовать, чтобы избежать репликации вызова функции с большим количеством параметров: .
Далее приведен пример, в котором условный оператор встроен в строку, по существу используемый для правильного построения String в зависимости от того, является ли x единственным или множественным числом:
returnString = "There " + (x > 1 ? " are " + x + " cookies" : "is one cookie") + " in the jar."
Пример, демонстрирующих аналогичную операцию в String, на этот раз для правильного вывода приветствия для определенного пола человека:
returnString = "Thank you " + (person.isMale() ? "Mr. " : "Ms. ") + person.getLastName() + "."
Вот исходный код класса Java, который я использовал для тестирования некоторых примеров, показанных в этом руководстве:
public class JavaTernaryOperatorExamples { public static void main(String[] args) { // минимальное значение int minVal, a=3, b=2; minVal = a < b ? a : b; System.out.println("min = " + minVal); // абсолютное значение a = -10; int absValue = (a < 0) ? -a : a; System.out.println("abs = " + absValue); // результату присваивается значение 1.0 float result = true ? 1.0f : 2.0f; System.out.println("float = " + result); // результат присваивается значение "Извини, чувак, это ложь" String s = false ? "Dude, that was true" : "Sorry Dude, it's false"; System.out.println(s); // пример использования тернарного оператора в правой части строки int x = 5; String out = "There " + (x > 1 ? " are " + x + " cookies" : "is one cookie") + " in the jar."; System.out.println(out); } }
Оцени статью
Оценить
Средняя оценка / 5. Количество голосов:
Видим, что вы не нашли ответ на свой вопрос.
Помогите улучшить статью.
Спасибо за ваши отзыв!
Приоритеты операций
Все операции вычисляются слева направо (сначала вычисляется левый операнд, затем правый и затем сама операций, кроме операции присваивания. Операция присваивания вычисляется справа налево.
Вычисления производятся в соответствии с таблицей приоритетов операций, приведённой ниже. Операция, находящаяся выше в таблице, имеет более высокий приоритет, чем операция, находящаяся ниже, и вычиляется раньше. Операции, находящиеся на одной строке, имеют одинаковый приоритет. Если в одном выражении находится несколько разных операций, то сначала вычисляется результат операции с наивысшим приоритетом. Можно использовать скобки для указания того, что сначала нужно вычислить эту часть выражения.
Пример 1:
Java
int z = 200 * (3 + 4);
1 | intz=200*(3+4); |
Последовательность вычисляения такая:
- 3+4 = 7
- 200 * 7 = 1 400
- z = 1 400
Пример 2:
Java
int x;
int y;
int z = x = y = 10000 + 20000 >> 1 + 3 * 2;
1 |
intx; inty; intz=x=y=10000+20000>>1+3*2; |
Последовательность вычисления такая:
- 10 000 + 20 000 = 30 000 (Присвоение вычисляется справа налево, поэтому сначала смотрится
y=10000+20000>>1+3*2 , и вычисляется правая часть. В правой части (
10000+20000>>1+3*2 ) вычисление идёт слева направо, и берётся
10000+20000 (выбирается среди
10000+20000 ,
20000>>1 ,
1+3 и
3*2 ), которое вычисляется перед сдвигом, так как у сложения приоритет выше.) - 3 * 2 = 6 (В выражении
30000>>1+3*2 вычисление идёт слева направо, и выбирается умножение(среди
30000>>1 ,
1+3 и
3*2 ), так как у него приоритет выше, что означает, что сложение будет выполнено раньше.) - 1 + 6 = 7 (В выражении
30000>>1+6 вычисление идёт слева направо и сложение вычисляется раньше сдвига, так как приоритет у сложения выше.) - 30 000 >> 7 = 234 (0b00…111010100110000 сдвигаем на 7 бит вправо и получаем 0b00…0011101010)
- y = 234
- x = 234
- z = 234
Таблица приоритетов операций
Группа операций | Приоритет |
---|---|
Группировка | |
Доступ к члену | |
постфиксные | |
унарные | |
мультипликативные | |
аддитивные | |
сдвиги | |
сравнения | |
равенства | |
бинарный И | |
бинарный исключающее ИЛИ | |
бинарный ИЛИ | |
логический И | |
логический ИЛИ | |
тернарный | |
лямбда | |
присваивания |
Цикл статей «Учебник Java 8».
Следующая статья — «Java 8 выражения, инструкции и блоки».
Предыдущая статья — «Переменные в Java 8».
Создание и особенности
Создаётся интерфейс, как и любой класс:
Только вместо ключевого слова class используется interface. Область видимости интерфейса тоже можно указать, но только в том случае, если файл носит такое же имя.
В интерфейс удобно выносить некие абстрактные свойства и функции объектов. Например, метод eat(). Кушать могут все создания на земле. И при реализации отдельных видов, например, животных, можно использовать интерфейс.
Также стоит обратить внимание, что метод eat() не имеет реализации. И в этом заключается особенность интерфейса
Так как мы не знаем, как ест каждый отдельный вид животных, то и реализовывать отдельный механизм надо непосредственно при разработке функционала объекта.
Чтобы использовать механизм интерфейса в классе, надо после его имени указать ключевое слово implements и добавить имя. Любая среда разработки сразу же сообщит, что раз класс реализует некий интерфейс, то его методы должны быть добавлены в класс и переопределены.
После добавления метода интерфейса в представленный класс, мы может конкретизировать его реализацию. В данном случае мы выводим сообщение о том, как собаки любят есть — грызть кость. Для другого животного можно было описать другой способ потребления пищи — коты пьют молоко, мышки едят сыр, коровы щиплют траву. То есть мы абстрагировали общий для всех объектов функционал, а затем в каждом конкретном случае уточнили как именно это происходит. В этом и заключается механизм работы интерфейсов.
Стоит отметить, что в Java 8 появился новый подход к реализации методов. С помощью ключевого слова defaultможно указать метод, общий для всех и добавить его реализацию прямо в интерфейс. Например, коты, собаки и коровы ходят на 4 лапах и ногах, но едят разную пищу. Это значит, что можно вынести одинаковый функционал в отдельный метод.
Теперь при реализации этого интерфейса в классе нет необходимости указывать его точную реализацию. Она просто выполнится по умолчанию при вызове.
Теперь о наследовании. Так как Javaне поддерживает множественное наследование, интерфейсы частично могут решить эту проблему. Реализовывать интерфейсов в одном классе можно сколько угодно, указав их через запятую после слова implements.
При необходимости, интерфейсы можно наследовать друг от друга, также, как и классы, с помощью ключевого слова extends. Но, в отличие от классов, через запятую можно указать несколько имён и реализовать таким образом множественное наследование.
JavaScript: Табnица истинности
Основными логическими или булевыми операциями, названными в честь одного из математиков — Джорджа Буля (1815-1864), являются:
- ИЛИ – логическое сложение (дизъюнкция) – OR;
- И – логическое умножение (конъюнкция) – AND;
- НЕ – логическое отрицание (инверсия) – NOT.
Логические операторы работают с операндами так же, как и с булевыми значениями, возвращая или , поэтому эти операции можно описать таблицей истинности, в которой полностью описано их поведение:
X | Y | X || Y | X && Y | !X |
---|---|---|---|---|
false | false | false | false | true |
true | false | true | false | false |
false | true | true | false | true |
true | true | true | true | false |
Из этой таблицы видно, что результатом работы оператора ИЛИ будет , только если оба его операнда – ; результатом оператора И будет , только если оба из его операндов – . Оператор НЕ прост – он получает один операнд и возвращает обратное значение.
Логические операторы не требуют, что бы их операнды были логическими значениями. Стоит отметить, что все значения в языке JavaScript являются либо истинными , либо ложными .
Ложными () значениями являются , , , , , и (пустя строка). Все другие значения, включая все объекты, являются истинными ().
Пример 2: Арифметические операторы
class ArithmeticOperator { public static void main(String[] args) { double number1 = 12.5, number2 = 3.5, result; // Используется оператор сложения result = number1 + number2; System.out.println("number1 + number2 = " + result); // Используется оператор вычитания result = number1 - number2; System.out.println("number1 - number2 = " + result); // Используется оператор умножения result = number1 * number2; System.out.println("number1 * number2 = " + result); // Используется оператор деления result = number1 / number2; System.out.println("number1 / number2 = " + result); // Используется оператор остатка result = number1 % number2; System.out.println("number1 % number2 = " + result); } }
Когда вы запустите программу, на экран выведется:
number1 + number2 = 16.0 number1 - number2 = 9.0 number1 * number2 = 43.75 number1 / number2 = 3.5714285714285716 number1 % number2 = 2.0
В примере с оператором деления Java, приведенном выше, использованные операнды – переменные. Кроме этого могут использоваться символьные значения. Например:
result = number1 + 5.2; result = 2.3 + 4.5; number2 = number1 -2.9;
Оператор «+» также может быть использован, чтобы соединить (конкатенировать) две строки или больше.
Операция присваивания
Операция «=» позволяет присвоить значение переменной:
Java
int x = 3;
long l1 = 10_000_000_000L;
float f1 = 1.3f;
double weight = 81.34;
byte b1 = 100;
short sh1 = -10000;
char ch1 = 60000;
1 |
intx=3; longl1=10_000_000_000L; floatf1=1.3f; doubleweight=81.34; byteb1=100; shortsh1=-10000; charch1=60000; |
КОНСТАНТНЫЕ значения до
int можно присвоить без приведения типа к переменным меньшего размера (например
short в
byte), если значение помещается в эту переменную.
Вы можете присвоить переменной, имеющей больший тип, значение меньшего типа, например переменной типа
double можно присвоить значение
int, но не наоборот (но можно использовать приведение типа, если очень нужно).
Примеры:
Java
double d1 = 2; // Это можно
int x = 2.3; // так нельзя. Будет ошибка компиляции.
byte b1 = 100; //Это можно, так как литерал 100 гарантировано
// поместится в byte.
byte b2 = 10000; //Нельзя. Ошибка компиляции.
int n = 100;
byte b3 = n; //А вот так тоже нельзя, так как
// переменная n имеет тип int.
1 |
doubled1=2;// Это можно intx=2.3;// так нельзя. Будет ошибка компиляции. byteb1=100;//Это можно, так как литерал 100 гарантировано // поместится в byte. byteb2=10000;//Нельзя. Ошибка компиляции. intn=100; byteb3=n;//А вот так тоже нельзя, так как // переменная n имеет тип int. |
Операция присваивания возвращает значение, которое присвоила, поэтому можно присваивать значение сразу нескольким переменным по цепочке:
Java
int x;
int y;
int z = x = y = 10; // y, x и z будет присвоено 10.
1 |
intx; inty; intz=x=y=10;// y, x и z будет присвоено 10. |
Mutable vs Immutable объекты
Когда-то давно мы с вами изучали константы в Java и пришли к не очень утешительному выводу. Константы позволяют защитить переменные от изменений, но не в состоянии защитить от изменений объекты, на которые эти переменные ссылаются.
В ответ на эту проблему в Java придумали объекты-константы. Или, как их еще называют, immutable-объекты — неизменяемые объекты.
Кстати, вы даже знаете один такой класс, чьи объекты нельзя менять — . Объект класса остается неизменным все время после создания. И как же разработчики Java добились этого?
Во-первых, все переменные класса скрыты – объявлены .
Во-вторых, наследоваться от класса нельзя: он имеет модификатор в объявлении класса.
В-третьих, что самое интересное, все методы класса , которые по идее должны были менять существующий объект, не меняют его, а возвращают новый.
Например, метод делает все буквы строки большими (заглавными). Но вместо изменения объекта, у которого он вызван, этот метод возвращает новый объект типа , состоящий из заглавных букв:
Вот что будет в памяти после выполнения этого кода:
Так что смело передавайте ваши строки в любые методы: никто их не поменяет.
Оператор while
Оператор
while позволяет выполнить инструкцию или блок инструкций несколько раз.
Его синтаксис:
while (<условие>)
<оператор1>;
1 |
while (<условие>) <оператор1>; |
И с блоком операторов/инструкций (согласно соглашению о кодировании Java рекомендуется использовать вариант с блоком даже в случае одной инструкции):
while (<условие>) {
<оператор1>;
<оператор2>;
…
<оператор3>;
}
1 |
while (<условие>) { <оператор1>; <оператор2>; … <оператор3>; } |
Оператор
while вычисляет выражение
<условие> и выполняет оператор или блок операторов, если результат выражения
<условие> равен
true. Затем он ещё раз вычисляет и проверяет
<условие> и, если оно вернуло
true, то снова выполняет оператор или блок операторов. Так выполняется до тех пор, пока
<условие> не вернёт
false.
Следующий код выведет числа от 0 до 10:
Java
int n = 0;
while (n <= 10) {
System.out.println(n);
n++;
}
1 |
intn=; while(n<=10){ System.out.println(n); n++; } |
Выражение
<условие> в
while может быть любым, но оно обязательно должно возвращать тип
boolean. Следующий код тоже корректен:
Java
// Бесконечный цикл
while (true) {
// операторы
}
// Это тоже корректный код, но obj1 должен
// иметь метод someMethodReturnsBoolean(),
// возвращающий boolean.
boolean b;
while (b = obj1.someMethodReturnsBoolean()) {
// операторы
}
1 |
// Бесконечный цикл while(true){ // операторы } booleanb; while(b=obj1.someMethodReturnsBoolean()){ // операторы } |
Оператор switch
Рассмотрим следующий кусок кода:
Java
if (mode == 0) {
// operators for mode 0
} else if (mode == 1) {
// operators for mode 1
} else if (mode == 2) {
// operators for mode 2
} else {
// operators for other mode.
}
1 |
if(mode==){ // operators for mode 0 }elseif(mode==1){ // operators for mode 1 }elseif(mode==2){ // operators for mode 2 }else{ // operators for other mode. } |
В куске кода, приведённом выше, проверяется значение переменной
mode. Для значений 0, 1 и 2 предусмотрены отдельные блоки кода, и ещё один блок кода предусмотрен для всех остальных значений. Оператор
switch делает то же самое, но делает код более наглядным:
Java
switch (mode) {
case 0:
// operators for mode 0
break;
case 1:
// operators for mode 1
break;
case 2:
// operators for mode 2
break;
default:
// operators for other mode
break;
}
1 |
switch(mode){ case // operators for mode 0 break; case1 // operators for mode 1 break; case2 // operators for mode 2 break; default // operators for other mode break; } |
Этот кусок кода с оператором
switch делает абсолютно то же самое, что и кусок кода с
if, рассмотренный до этого, но рекомендуется использовать вариант со
switch, так как он более нагляден.
Оператор
switch работает в следующем порядке:
- Вычисляется выражение в скобках (в данном примере оно состоит просто из переменной
mode ) - Полученное значение проверяется подряд со значениями в
case , и выполняется тот блок операторов, который относится к
case со значением, совпадающим со значением выражения. - Если ни одно из значений не совпало, то выполняется блок
default. - По ключевому слову
break выполнение блока внутри
case или
default завершается и управление передаётся на следующую инструкцию за блоком
switch.
С помощью
if-then и
if-then-else можно проверять любые условия, но с помощью
switch можно проверять только значения выражений типа
byte ,
short ,
char ,
int , перечисления (будет описано позднее),
String (начиная с Java SE 7), а также классы
java.lang.Byte ,
java.lang.Short ,
java.langCharacter ,
java.lang.Integer. Проверяемые значения в
case обязательно должны быть константными литералами. Если значение выражения в
switch равно
null, то возникает
java.lang.NullPointerException. Нагляднее всего
switch выглядит именно с перечислениями.
Ключевое слово
break не обязательно. В случае его отсутствия по завершении выполнения блока операторов внутри одного
case выполняются операторы следующего за ним
case. Это позволяет использовать один блок операторов для нескольких значений
case:
Java
switch (mode) {
case -1:
System.out.println(«mode -1»);
break;
case 0:
System.out.println(«mode 0»);
case 1:
case 2:
System.out.println(«mode 0 or 1 or 2»);
break;
case 3:
System.out.println(«mode 2»);
break;
default:
System.out.println(«mode default»);
break;
}
1 |
switch(mode){ case-1 System.out.println(«mode -1»); break; case System.out.println(«mode 0»); case1 case2 System.out.println(«mode 0 or 1 or 2»); break; case3 System.out.println(«mode 2»); break; default System.out.println(«mode default»); break; } |
Если
mode равно 0, то код выше выведет в консоль:
mode 0
mode 0 or 1 or 2
1 |
mode 0 mode 0 or 1 or 2 |
Если
mode равно 1, то код выше выведет в консоль:
mode 0 or 1 or 2
1 | mode 0 or 1 or 2 |
Если
mode равно 2, то код выше выведет в консоль:
mode 0 or 1 or 2
1 | mode 0 or 1 or 2 |
Блок
default не обязательно указывать в конце блока
switch. Он может стоять и в начале, и в середине (но рекомендуется всегда писать его последним, так получается гораздо нагляднее, потому что он выполняется в том случае, если ни один из
case -ов не подошёл):
Java
switch (mode) {
case 0:
System.out.println(«mode 0»);
break;
default:
System.out.println(«mode default»);
break;
case 1:
System.out.println(«mode 1»);
break;
case 2:
System.out.println(«mode 2»);
break;
}
1 |
switch(mode){ case System.out.println(«mode 0»); break; default System.out.println(«mode default»); break; case1 System.out.println(«mode 1»); break; case2 System.out.println(«mode 2»); break; } |
Можно даже вообще не указывать блок
default:
Java
switch (mode) {
case 0:
System.out.println(«mode 0»);
break;
case 1:
System.out.println(«mode 1»);
break;
case 2:
System.out.println(«mode 2»);
break;
}
1 |
switch(mode){ case System.out.println(«mode 0»); break; case1 System.out.println(«mode 1»); break; case2 System.out.println(«mode 2»); break; } |
Java Integer Math
Математические операции, выполняемые с целочисленными типами Java (byte, short, int и long), ведут себя немного иначе, чем обычные математические операции. Поскольку целочисленные типы не могут содержать дроби, в каждом вычислении с одним или несколькими целочисленными типами все дроби в результате обрезаются. Посмотрите на это математическое выражение:
int result = 100 / 8;
Результат этого деления будет 12,5, но так как два числа являются целыми числами, фракция .5 обрезается. Результат, следовательно, всего 12.
Округление также происходит в подрезультатах больших вычислений.
С плавающей точкой Math
Java содержит два типа данных с плавающей точкой: float и double. Они могут содержать дроби в числах. Если нужны дробные выражения в математических выражениях, вы должны использовать один из этих типов данных. Вот пример математического выражения с плавающей точкой:
double result = 100 / 8;
Несмотря на то, что переменная результата теперь имеет тип с плавающей запятой (double), конечный результат по-прежнему равен 12 вместо 12,5. Причина в том, что оба значения в математическом выражении (100 и 8) оба являются целыми числами. Таким образом, результат деления одного на другое сначала преобразуется в целое число (12), а затем присваивается переменной результата.
Чтобы избежать округления вычислений, необходимо убедиться, что все типы данных, включенные в математическое выражение, являются типами с плавающей запятой. Например, вы могли бы сначала присвоить значения переменным с плавающей запятой следующим образом:
double no1 = 100; double no2 = 8; double result = no1 / no2;
Теперь переменная результата будет иметь значение 12,5.
В Java есть способ заставить все числа в расчете быть переменными с плавающей точкой. Вы ставите числа с большой буквы F или D. Вот пример:
double result = 100D / 8D;
Обратите внимание на прописные буквы D после каждого числа. Этот верхний регистр D говорит Java, что эти числа должны интерпретироваться как числа с плавающей запятой, и, таким образом, деление должно быть делением с плавающей запятой, которое сохраняет дроби вместо их обрезания
На самом деле вы также можете сделать число длинным, добавив суффикс числа к верхнему регистру L, но long по-прежнему является целочисленным типом, поэтому он не будет сохранять дробные части в вычислениях.
Точность с плавающей точкой
Типы данных с плавающей точкой не являются точными на 100%. Вы можете столкнуться с ситуациями, когда числа со многими дробями не складываются с ожидаемым числом. Если вычисление с плавающей запятой приводит к числу с большим количеством дробей, чем может обработать число с плавающей запятой или двойное число, дроби могут быть обрезаны. Конечно, заданная точность может быть более чем достаточной для многих типов вычислений, но имейте в виду, что дроби могут фактически быть отсечены.
Посмотрите:
double resultDbl3 = 0D; System.out.println("resultDbl3 = " + resultDbl3); for(int i=0; i<100; i++){ resultDbl3 += 0.01D; } System.out.println("resultDbl3 = " + resultDbl3);
Вывод выводится при выполнении этого кода с Java 8:
resultDbl3 = 0.0 resultDbl3 = 1.0000000000000007
Первый оператор System.out.println() правильно печатает значение 0.0, которое является начальным значением переменной resultDbl3.
Однако второй оператор System.out.println() выводит несколько странный результат. Добавление значения 0,01 к 0 всего 100 раз должно привести к значению 1,0, верно? Но каким-то образом окончательный результат 1.0000000000000007. Как видите, что-то не так во фракциях.
Обычно неточность с плавающей запятой незначительна, но все же важно знать об этом
Операторы присваивания
Вот это язык Java для поддержки оператора присваивания:
операторы | описание | пример |
---|---|---|
= | Простой оператор присваивания, значение правого операнда левого операнда | C = A + B + B даст значение, присвоенное C |
+ = | Сложение и оператор присваивания, то левый операнд и правый операнд, добавив задание левого операнда | С + = А эквивалентно C = C + A |
— = | Сохранить левый операнд и оператор присваивания, то левый операнд и правый операнд назначается для вычитания | С — = А эквивалентно С = С — |
* = | Умножение и оператор присваивания, то левый операнд и правый операнд умножается на присвоение левого операнда | С * = А эквивалентно C = C * A |
/ = | Кроме того и оператор присваивания, то левый операнд и правый операнд деление назначен на левый операнд | С / = А эквивалентно C = C / A |
(%) = | Модульное и оператор присваивания, то левый операнд и правый операнд левого операнда после присваивания по модулю | С% = А эквивалентно С = С% А |
<< = | Оператор присваивания сдвига влево | C << = 2 эквивалентно C = C << 2 |
>> = | Оператор присваивания Сдвиг вправо | C >> = 2 эквивалентно C = C >> 2 |
& = | Побитовое И оператор присваивания | C & = 2 эквивалентно С = С & 2 |
^ = | Оператор присваивания Побитовая XOR | C ^ = 2 эквивалентно С = С ^ 2 |
| = | Побитовое ИЛИ оператор присваивания | C | = 2 эквивалентно С = С | 2 |
примеров
Простой пример показывает, что программы сталкиваются оператор присваивания. Скопируйте и вставьте следующую программу Java и сохранить его как Test.java файл, а затем скомпилировать и запустить эту программу:
public class Test { public static void main(String args[]) { int a = 10; int b = 20; int c = 0; c = a + b; System.out.println("c = a + b = " + c ); c += a ; System.out.println("c += a = " + c ); c -= a ; System.out.println("c -= a = " + c ); c *= a ; System.out.println("c *= a = " + c ); a = 10; c = 15; c /= a ; System.out.println("c /= a = " + c ); a = 10; c = 15; c %= a ; System.out.println("c %= a = " + c ); c <<= 2 ; System.out.println("c <<= 2 = " + c ); c >>= 2 ; System.out.println("c >>= 2 = " + c ); c >>= 2 ; System.out.println("c >>= a = " + c ); c &= a ; System.out.println("c &= 2 = " + c ); c ^= a ; System.out.println("c ^= a = " + c ); c |= a ; System.out.println("c |= a = " + c ); } }
Приведенные выше примеры скомпилированные получены следующие результаты:
c = a + b = 30 c += a = 40 c -= a = 30 c *= a = 300 c /= a = 1 c %= a = 5 c <<= 2 = 20 c >>= 2 = 5 c >>= 2 = 1 c &= a = 0 c ^= a = 10 c |= a = 10