Сдам Сам

ПОЛЕЗНОЕ


КАТЕГОРИИ







Приоритет арифметических операций





Одни операции имеют больший приоритет чем другие и поэтому выполняются вначале. Операции в порядке уменьшения приоритета:

++ (инкремент), -- (декремент)

* (умножение), / (деление), % (остаток от деления)

+ (сложение), - (вычитание)

Приоритет операций следует учитывать при выполнении набора арифметических выражений:

  inta = 8; intb = 7; intc = a + 5* ++b; System.out.println(c); // 48

Вначале будет выполняться операция инкремента ++b, которая имеет больший приоритет - она увеличит значение переменной b и возвратит его в качестве результата. Затем выполняется умножение 5 * ++b, и только в последнюю очередь выполняется сложение a + 5 * ++b

Скобки позволяют переопределить порядок вычислений:

  inta = 8; intb = 7; intc = (a + 5) * ++b; System.out.println(c); // 104

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

Ассоциативность операций

Кроме приоритета операции отличаются таким понятием как ассоциативность. Когда операции имеют один и тот же приоритет, порядок вычисления определяется ассоциативностью операторов. В зависимости от ассоциативности есть два типа операторов:

· Левоассоциативные операторы, которые выполняются слева направо

· Правоассоциативные операторы, которые выполняются справа налево

Так, некоторые операции, например, операции умножения и деления, имеют один и тот же приоритет. Какой же тогда будет результат в выражении:

  intx = 10/ 5* 2;

Стоит нам трактовать это выражение как (10 / 5) * 2 или как 10 / (5 * 2)? Ведь в зависимости от трактовки мы получим разные результаты.

Поскольку все арифметические операторы (кроме префиксного инкремента и декремента) являются левоассоциативными, то есть выполняются слева направо. Поэтому выражение 10 / 5 * 2 необходимо трактовать как (10 / 5) * 2, то есть результатом будет 4.

Операции с числами с плавающей точкой

Следует отметить, что числа с плавающей точкой не подходят для финансовых и других вычислений, где ошибки при округлении могут быть критичными. Например:

  doubled = 2.0- 1.1; System.out.println(d);

В данном случае переменная d будет равна не 0.9, как можно было бы изначально предположить, а 0.8999999999999999. Подобные ошибки точности возникают из-за того, что на низком уровне для представления чисел с плавающей точкой применяется двоичная система, однако для числа 0.1 не существует двоичного представления, также как и для других дробных значений. Поэтому если в таких случаях обычно применяется класс BigDecimal, который позволяет обойти подобные сиуации.

Побитовые операции

Побитовые или поразрядные операции выполняются над отдельными разрядами или битами чисел. В данных операциях в качестве операндов могу выступать только целые числа.

Каждое число имеет определенное двоичное представление. Например, число 4 в двоичной системе 100, а число 5 - 101 и так далее.

К примеру, возьмем следующие переменны:

  byteb = 7; // 0000 0111 shorts = 7; // 0000 0000 0000 0111

Тип byte занимает 1 байт или 8 битов, соответственно представлен 8 разрядами. Поэтому значение переменной b в двоичном коде будет равно 00000111. Тип short занимает в памяти 2 байта или 16 битов, поэтому число данного типа будет представлено 16 разрядами. И в данном случае переменная s в двоичной системе будет иметь значение 0000 0000 0000 0111.

Для записи чисел со знаком в Java применяется дополнительный код (two’s complement), при котором старший разряд является знаковым. Если его значение равно 0, то число положительное, и его двоичное представление не отличается от представления беззнакового числа. Например, 0000 0001 в десятичной системе 1.

Если старший разряд равен 1, то мы имеем дело с отрицательным числом. Например, 1111 1111 в десятичной системе представляет -1. Соответственно, 1111 0011 представляет -13.

Логические операции

Логические операции над числами представляют поразрядные операции. В данном случае числа рассматриваются в двоичном представлении, например, 2 в двоичной системе равно 10 и имеет два разряда, число 7 - 111 и имеет три разряда.

· & (логическое умножение)

Умножение производится поразрядно, и если у обоих операндов значения разрядов равно 1, то операция возвращает 1, иначе возвращается число 0. Например:

  inta1 = 2; //010 intb1 = 5;//101 System.out.println(a1&b1); // результат 0   inta2 = 4; //100 intb2 = 5; //101 System.out.println(a2 & b2); // результат 4

В первом случае у нас два числа 2 и 5. 2 в двоичном виде представляет число 010, а 5 - 101. Поразрядное умножение чисел (0*1, 1*0, 0*1) дает результат 000.

Во втором случае у нас вместо двойки число 4, у которого в первом разряде 1, так же как и у числа 5, поэтому здесь результатом операции (1*1, 0*0, 0 *1) = 100 будет число 4 в десятичном формате.

· | (логическое сложение)

Данная операция также производится по двоичным разрядам, но теперь возвращается единица, если хотя бы у одного числа в данном разряде имеется единица (операция "логическое ИЛИ"). Например:

  inta1 = 2; //010 intb1 = 5;//101 System.out.println(a1|b1); // результат 7 - 111 inta2 = 4; //100 intb2 = 5;//101 System.out.println(a2 | b2); // результат 5 - 101

· ^ (логическое исключающее ИЛИ)

Также эту операцию называют XOR, нередко ее применяют для простого шифрования:

  intnumber = 45; // 1001 Значение, которое надо зашифровать - в двоичной форме 101101 intkey = 102; //Ключ шифрования - в двоичной системе 1100110 intencrypt = number ^ key; //Результатом будет число 1001011 или 75 System.out.println("Зашифрованное число: "+encrypt);   intdecrypt = encrypt ^ key; // Результатом будет исходное число 45 System.out.println("Расшифрованное число: "+ decrypt);

Здесь также производятся поразрядные операции. Если у нас значения текущего разряда у обоих чисел разные, то возвращается 1, иначе возвращается 0. Например, результатом выражения 9^5 будет число 12. А чтобы расшифровать число, мы применяем обратную операцию к результату.

· ~ (логическое отрицание)

Поразрядная операция, которая инвертирует все разряды числа: если значение разряда равно 1, то оно становится равным нулю, и наоборот.

  bytea = 12; // 0000 1100 System.out.println(~a); // 1111 0011 или -13

Операции сдвига

Операции сдвига также производятся над разрядами чисел. Сдвиг может происходить вправо и влево.

· a<<b - сдвигает число a влево на b разрядов. Например, выражение 4<<1 сдвигает число 4 (которое в двоичном представлении 100) на один разряд влево, в результате получается число 1000 или число 8 в десятичном представлении.

· a>>b - смещает число a вправо на b разрядов. Например, 16>>1 сдвигает число 16 (которое в двоичной системе 10000) на один разряд вправо, то есть в итоге получается 1000 или число 8 в десятичном представлении.

· a>>>b - в отличие от предыдущих типов сдвигов данная операция представляет беззнаковый сдвиг - сдвигает число a вправо на b разрядов. Например, выражение -8>>>2 будет равно 1073741822.

Таким образом, если исходное число, которое надо сдвинуть в ту или другую строну, делится на два, то фактически получается умножение или деление на два. Поэтому подобную операцию можно использовать вместо непосредственного умножения или деления на два, так как операция сдвига на аппаратном уровне менее дорогостоящая операция в отличие от операции деления или умножения.

Условные выражения

Условные выражения представляют собой некоторое условие и возвращают значение типа boolean, то есть значение true (если условие истинно), или значение false (если условие ложно). К условным выражениям относятся операции сравнения и логические операции.

Операции сравнения

В операциях сравнения сравниваются два операнда, и возвращается значение типа boolean - true, если выражение верно, и false, если выражение неверно.

· ==

сравнивает два операнда на равенство и возвращает true (если операнды равны) и false (если операнды не равны)

  inta = 10; intb = 4; booleanc = a == b; // false booleand = a == 10; // true

·!=

сравнивает два операнда и возвращает true, если операнды НЕ равны, и false, если операнды равны

  inta = 10; intb = 4; booleanc = a!= b; // true booleand = a!= 10; // false

· < (меньше чем)

Возвращает true, если первый операнд меньше второго, иначе возвращает false

  inta = 10; intb = 4; booleanc = a < b; // false

· > (больше чем)

Возвращает true, если первый операнд больше второго, иначе возвращает false

  inta = 10; intb = 4; booleanc = a > b; // true

· >= (больше или равно)

Возвращает true, если первый операнд больше второго или равен второму, иначе возвращает false

  booleanc = 10>= 10; // true booleanb = 10>= 4; // true booleand = 10>= 20; // false

· <= (меньше или равно)

Возвращает true, если первый операнд меньше второго или равен второму, иначе возвращает false

  booleanc = 10<= 10; // true booleanb = 10<= 4; // false booleand = 10<= 20; // true

Логические операции

Также в Java есть логические операции, которые также представляют условие и возвращают true или false и обычно объединяют несколько операций сравнения. К логическим операциям относят следующие:

· |

c=a|b; (c равно true, если либо a, либо b (либо и a, и b) равны true, иначе c будет равно false)

· &

c=a&b; (c равно true, если и a, и b равны true, иначе c будет равно false)

·!

c=!b; (c равно true, если b равно false, иначе c будет равно false)

· ^

c=a^b; (c равно true, если либо a, либо b (но не одновременно) равны true, иначе c будет равно false)

· ||

c=a||b; (c равно true, если либо a, либо b (либо и a, и b) равны true, иначе c будет равно false)

· &&

c=a&&b; (c равно true, если и a, и b равны true, иначе c будет равно false)

Здесь у нас две пары операций | и || (а также & и &&) выполняют похожие действия, однако же они не равнозначны.

Выражение c=a|b; будет вычислять сначала оба значения - a и b и на их основе выводить результат.

В выражении же c=a||b; вначале будет вычисляться значение a, и если оно равно true, то вычисление значения b уже смысла не имеет, так как у нас в любом случае уже c будет равно true. Значение b будет вычисляться только в том случае, если a равно false

То же самое касается пары операций &/&&. В выражении c=a&b; будут вычисляться оба значения - a и b.

В выражении же c=a&&b; сначала будет вычисляться значение a, и если оно равно false, то вычисление значения b уже не имеет смысла, так как значение c в любом случае равно false. Значение b будет вычисляться только в том случае, если a равно true

Таким образом, операции || и && более удобны в вычислениях, позволяя сократить время на вычисление значения выражения и тем самым повышая производительность. А операции | и & больше подходят для выполнения поразрядных операций над числами.

Примеры:

  booleana1 = (5> 6) || (4< 6); // 5 > 6 - false, 4 < 6 - true, поэтому возвращается true booleana2 = (5> 6) || (4> 6); // 5 > 6 - false, 4 > 6 - false, поэтому возвращается false booleana3 = (5> 6) && (4< 6); // 5 > 6 - false, 4 < 6 - true, поэтомувозвращается false booleana4 = (50> 6) && (4/ 2< 3); // 50 > 6 - true, 4/2 < 3 - true, поэтомувозвращается true booleana5 = (5> 6) ^ (4< 6); // 5 > 6 - false, 4 < 6 - true, поэтомувозвращается true booleana6 = (50> 6) ^ (4/ 2< 3); // 50 > 6 - true, 4/2 < 3 - true, поэтомувозвращается false






ЧТО ПРОИСХОДИТ ВО ВЗРОСЛОЙ ЖИЗНИ? Если вы все еще «неправильно» связаны с матерью, вы избегаете отделения и независимого взрослого существования...

Система охраняемых территорий в США Изучение особо охраняемых природных территорий(ООПТ) США представляет особый интерес по многим причинам...

Что способствует осуществлению желаний? Стопроцентная, непоколебимая уверенность в своем...

ЧТО И КАК ПИСАЛИ О МОДЕ В ЖУРНАЛАХ НАЧАЛА XX ВЕКА Первый номер журнала «Аполлон» за 1909 г. начинался, по сути, с программного заявления редакции журнала...





Не нашли то, что искали? Воспользуйтесь поиском гугл на сайте:


©2015- 2024 zdamsam.ru Размещенные материалы защищены законодательством РФ.