• Logical operators. Arithmetic operations

    Latest update: 30.10.2018

    Most of the operations in Java are similar to those used in other C-like languages. There are unary operations (performed on one operand), binary operations on two operands, and ternary operations on three operands. An operand is a variable or value (such as a number) involved in an operation. Let's consider all types of operations.

    Arithmetic operations involve numbers. Java has binary arithmetic operations (performed on two operands) and unary arithmetic operations (performed on one operand). Binary operations include the following:

      operation of adding two numbers:

      Int a = 10; int b = 7; int c = a + b; // 17 int d = 4 + b; // 11

      operation of subtracting two numbers:

      Int a = 10; int b = 7; int c = a - b; // 3 int d = 4 - a; // -6

      operation of multiplying two numbers

      Int a = 10; int b = 7; int c = a * b; // 70 int d = b * 5; // 35

      operation of dividing two numbers:

      Int a = 20; int b = 5; int c = a / b; // 4 double d = 22.5 / 4.5; // 5.0

      One thing to keep in mind when dividing is that if the operation involves two integers, the result of the division will be rounded to the nearest integer, even if the result is assigned to a float or double variable:

      Double k = 10 / 4; // 2 System.out.println(k);

      For the result to represent a floating point number, one of the operands must also represent a floating point number:

      Double k = 10.0 / 4; // 2.5 System.out.println(k);

      getting the remainder when dividing two numbers:

      Int a = 33; int b = 5; int c = a % b; // 3 int d = 22% 4; // 2 (22 - 4*5 = 2)

    There are also two unary arithmetic operations that are performed on a single number: ++ (increment) and -- (decrement). Each of the operations has two varieties: prefix and postfix:

      ++ (prefix increment)

      Involves increasing a variable by one, for example z=++y (first the value of the variable y is increased by 1, and then its value is assigned to the variable z)

      Int a = 8; int b = ++a; System.out.println(a); // 9 System.out.println(b); // 9

      ++ (postfix increment)

      Also represents an increase in a variable by one, for example z=y++ (first the value of the variable y is assigned to the variable z, and then the value of the variable y is increased by 1)

      Int a = 8; int b = a++; System.out.println(a); // 9 System.out.println(b); // 8

      -- (prefix decrement)

      decreasing a variable by one, for example, z=--y (first the value of the variable y is decreased by 1, and then its value is assigned to the variable z)

      Int a = 8; int b = --a; System.out.println(a); // 7 System.out.println(b); // 7

      -- (postfix decrement)

      z=y-- (first the value of the variable y is assigned to the variable z, and then the value of the variable y is decremented by 1)

      Int a = 8; int b = a--; System.out.println(a); // 7 System.out.println(b); // 8

    Priority of arithmetic operations

    Some operations have higher priority than others and are therefore performed first. Operations in decreasing order of priority:

    ++ (increment), -- (decrement)

    * (multiplication), / (division), % (division remainder)

    + (addition), - (subtraction)

    The precedence of operations should be taken into account when executing a set of arithmetic expressions:

    Int a = 8; int b = 7; int c = a + 5 * ++b; System.out.println(c); // 48

    The increment operation ++b will be executed first, which has higher priority - it will increment the value of variable b and return it as the result. Then the multiplication 5 * ++b is performed, and only lastly the addition a + 5 * ++b is performed

    Parentheses allow you to redefine the order of calculations:

    Int a = 8; int b = 7; int c = (a + 5) * ++b; System.out.println(c); // 104

    Even though the addition operation has a lower priority, the addition will be performed first, not the multiplication, since the addition operation is enclosed in parentheses.

    Associativity of operations

    In addition to priority, operations differ in such a concept as associativity. When operations have the same priority, the order of evaluation is determined by the associativity of the operators. Depending on the associativity, there are two types of operators:

      Left-associative operators, which are executed from left to right

      Right-associative operators, which are executed from right to left

    Thus, some operations, such as multiplication and division, have the same priority. What then will be the result in the expression:

    Int x = 10 / 5 * 2;

    Should we interpret this expression as (10 / 5) * 2 or as 10 / (5 * 2)? After all, depending on the interpretation, we will get different results.

    Because all arithmetic operators (except prefix increment and decrement) are left-associative, that is, they are executed from left to right. Therefore, the expression 10 / 5 * 2 must be interpreted as (10 / 5) * 2, that is, the result will be 4.

    Floating point operations

    It should be noted that floating point numbers are not suitable for financial and other calculations where rounding errors can be critical. For example:

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

    IN in this case the variable d will not be equal to 0.9, as one might initially assume, but 0.8999999999999999. These precision errors arise because at a low level the binary system is used to represent floating-point numbers, but there is no binary representation for the number 0.1, nor for other fractional values. Therefore, in such cases, the BigDecimal class is usually used, which allows you to bypass such situations.

    Most operations on primitive types is performed not using methods, but using special characters, called operation sign.

    Assignment operator

    Assignment value variable a constant, another variable or expression (variables and/or constants separated by operator signs) is called assignment operation and is indicated by the sign " = ", for example: x = 3; y = x; z = x; In Java, it is possible to use the assignment operator multiple times in one expression, for example: x1 = x2 = x3 = 0 ; This operation is performed from right to left, i.e. first to the variable x3 is assigned the value 0, then the variable x2 is assigned the value of the variable x3 (0), and finally the variable x1 is assigned the value of the variable x2 (0). The signs of operations whose arguments are numbers are divided into two categories: unary(unary) signs of operations with one argument and binary(binary) with two arguments.

    Unary operations

    The following unary operators are defined in Java:
    • unary minus " - " – changes the sign of a number or expression to the opposite;
    • unary plus " + " – does not perform any actions on a number or expression;
    • bitwise complement "~" (for integers only) – inverts all bits of the number field (changes 0 to 1 and 1 to 0);
    • increment "++" (for integers only) – increases the value of the variable by 1;
    • decrement " -- " (for integers only) – decreases the value of the variable by 1.
    Examples of unary operations " + " and " - ": int i = 3 , j, k; j= - i; // j = -3 k = + i; // k = 3 Example of bitwise complement operation: int a = 15 ; int b; b = ~a; // b = -16 Numbers a and b are numbers of type int , i.e. are represented internally by the computer as signed binary integers of length 32 bits, so the binary representation of numbers a and b would look like this: a = 00000000 00000000 00000000 00001111 b = 11111111 11111111 11111111 11110000 As you can see from this representation, all zero bits in number a are changed to one bits in b, and the one bits in a are changed to zero bits. The decimal representation of b is –16. Increment and decrement operation signs can be placed either before or after the variable. These options are named accordingly prefix And postfix recording these transactions. The operator sign in prefix notation returns the value of its operand after expression evaluation. In postfix notation, the operation sign at first returns the value of its operand and only after that calculates the increment or decrement, for example: int x = 1, y, z; y = ++x; z= x++ ; The variable y will be assigned the value 2 because first the value of x will be incremented by 1 and then the result will be assigned to the variable y . The variable z will be assigned the value 1 because first the variable z will be assigned a value and then the value of x will be incremented by 1 . In both cases, the new value of x will be 2. It should be noted that in Java, unlike the C language, decrement and increment operations can also be applied to real variables (type float and double). Binary Operation Signs are divided into operations with a numerical result and comparison operations, the result of which is a Boolean value.

    Arithmetic binary operations

    Java defines the following arithmetic binary operations:
    • addition "+";
    • subtraction " - ";
    • multiplication " * ";
    • division "/";
    • calculating the remainder of the division of integers "%" (returns the remainder of the division of the first number by the second, and the result will have the same sign as the dividend), for example, the result of the operation 5%3 will be equal to 2, and the result of the operation (-7) %(-4) will be equal to -3. In Java, the operation can also be used for real variables (type float or double).
    Binary examples arithmetic operations: int x = 7 , x1, x2, x3, x4, x5; x1 = x + 10 ; // x1 = 17 x2 = x – 8 ; // x2 = -1 x3 = x2 * x; // x3 = -7 x4 = x/ 4 ; // x4 = 1 (when dividing integers // fractional part is discarded) x5 = x% 4 // x5 = 3 (division remainder// 7 by 4)

    Bitwise operations

    • Bitwise operations treat raw numeric values ​​as fields of bits and perform the following operations on them:
    • setting bit in i The th position of the result field is 1 if both bits are in i The th positions of the operands are equal to 1, or 0 otherwise – bitwise AND ("& ");
    • setting bit in i The th position of the result field is 1 if at least one bit in i th positions of the operands is equal to 1, or 0 otherwise – bitwise OR (" | ");
    • setting bit in i The th position of the result field is 1 if the bits are in i-th positions of the operands are not equal to each other, or at 0 otherwise – bitwise exclusive OR (" ^ ");
    • shift to the left of the bits of the field of the first operand by the number of bits determined by the second operand (the sign bit of the number does not change) - bitwise shift to the left taking into account the sign "<< ";
    • right shift of the bits of the first operand field by the number of bits determined by the second operand (the sign bit of the number does not change) – bitwise shift to the right, taking into account the " >> " sign;
    • shift to the right of the bits of the field of the first operand by the number of bits determined by the second operand (the sign bit of the number is also shifted) - bitwise shift to the right without taking into account the " >>> " sign.
    Examples of bitwise operations:
    1. Bitwise AND

      int x = 112 ; int y = 94 ; int z; z = x & y; // z=80: 00000000 00000000 00000000 01010000
    2. Bitwise OR

      int x = 112 ; // x: 00000000 00000000 00000000 01110000 int y = 94 ; // y: 00000000 00000000 00000000 01011110 int z; z = x | y; // z = 126: 00000000 00000000 00000000 01111110
    3. Bitwise exclusive OR

      int x = 112 ; // x: 00000000 00000000 00000000 01110000 int y = 94 ; // y: 00000000 00000000 00000000 01011110 int z; z = x^y; // z = 46: 00000000 00000000 00000000 00101110
    4. Left shift based on sign

      int x = 31 , z; // x: 00000000 00000000 00000000 00011111 z = x<< 2 ; // z = 124: 00000000 00000000 00000000 01111100
    5. Right shift with sign

      int x = - 17 , z; z = x >> 2 ; // z = -5: 11111111 11111111 11111111 11111011
    6. Right shift without taking into account sign

      int x = - 17 , z; // x: 11111111 11111111 11111111 11101111 z = x >>> 2 ; // z = 1073741819 // z: 00111111 11111111 11111111 11111011

    Combined operations

    In Java, for binary arithmetic operations you can use combined(composite) operator signs: identifier operation = expression This is equivalent to the following operation: identifier = identifier operation expression Examples:
    1. The expression x += b means x = x + b.
    2. The expression x -= b means x = x - b .
    3. The expression x *= b means x = x * b .
    4. The expression x /= b means x = x / b.
    5. The expression x %= b means x = x % b .
    6. The expression x &= b means x = x & b .
    7. The expression x |= b means x = x | b.
    8. The expression x ^= b means x = x ^ b .
    9. Expression x<<= b означает x = x << b .
    10. The expression x >>= b means x = x >> b .
    11. The expression x >>>= b means x = x >>> b .

    Comparison Operations

    Java defines the following comparison operators:
    • " == " (equal), " != " (not equal),
    • " > " (greater than), " >= " (greater than or equal to),
    • " < " (меньше) " <= " (меньше или равно)
    have two operands and return a boolean value corresponding to the result of the comparison ( false or true). Please note that when comparing two quantities for equality in Java, as in C and C++, the symbols " == " (two consecutive equal signs without a space), as opposed to the assignment operator, which uses the symbol " = ". Using the " = " symbol when comparing two values ​​either causes a compilation error or leads to an incorrect result. Examples of comparison operations: boolean isEqual, isNonEqual, isGreater, isGreaterOrEqual, isLess, isLessOrEqual; int x1 = 5, x2 = 5, x3 = 3, x4 = 7; isEqual = x1 == x2; // isEqual = true isNonEqual = x1 != x2; // isNonEqual = false isGreater = x1 > x3; // isGreater = true // isGreaterOrEqual = true isGreaterOrEqual = x2 >= x3; isLess = x3< x1; // isLess = true isLessOrEqual = x1 <= x3; // isLessOrEqual = false

    Boolean operations

    Boolean operations are performed on Boolean variables and their result is also a value of type boolean. The following Boolean operations are defined in Java:
    • negation "!" – replacing false with true, or vice versa;
    • AND operation "&" – the result is true only if both operands are true, otherwise the result is false;
    • OR operation "|" – the result is true only if at least one of the operands is true, otherwise the result is false.
    • exclusive OR operation "^" – the result is true only if the operands are not equal to each other, otherwise the result is false.
    The operations " & ", " | " and " ^ " can, as well as the corresponding bitwise operations, be used in compound assignment operations: " &= ", " |= " and " ^= " In addition, the operations " = " are applicable to Boolean operands = " (equal) and " != " (not equal). As you can see from the definition of the OR and AND operators, the OR operation results in the result true when the first operand is true, regardless of the value of the second operand, and the AND operation results in the result false when the first operand is false, regardless of the value of the second operand. Java defines two more Boolean operators: second versions of the Boolean AND and OR operators, known as short-circuit logical operators: short-AND "&&" and short-circuit OR "||". When using these operations, the second operand will not be evaluated at all, which is useful in cases where the correct functioning of the right operand depends on whether the left operand is true or false . Examples of Boolean operations: boolean isInRange, isValid, isNotValid, isEqual, isNotEqual; int x = 8 ; isInRange = x > 0 && x< 5 ; // isInRange = false isValid = x >0 || x > 5 ; // isValid = true isNotValid = ! isValid; // isNotValid = false isEqual = isInRange == isValid; // isEqual = false // isNotEqual = true isNotEqual = isInRange != isValid

    Conditional operation

    The conditional operation is written in the form expression-1?expression-2:expression-3. In this case, the expression expression-1 is first evaluated, which should give a Boolean value, and then, if expression-1 is true, expression-2 is evaluated and returned as the result of the operation, or (if expression-1 is false), it is evaluated and , as a result of the operation, expression-3 is returned. Example of a conditional operation: x= n> 1 ? 0 : 1 ; The variable x will be assigned the value 0 if n>1 (the expression n>1 is true) or 1 if n≤1 (the expression n>1 is false).

    Operation seniority

    Operations in expressions are performed from left to right, however, in accordance with their priority. So the multiplication operations in the expression y = x + z* 5; will be executed before the addition operation because the priority of the multiplication operation is higher than the priority of the addition operation. The priorities of operations (in order of decreasing priority) in Java are given in table. 1.
    Parentheses increase the precedence of the operations that are inside them. So, if you insert parentheses into the above expression: y = (x + z) * 5 ; then the addition operation will be performed first, and then the multiplication operation. Sometimes parentheses are used simply to make an expression more readable, for example: (x > 1 ) && (x<= 5 ) ;

    Conversion and casting when performing operations

    Assignment operations and arithmetic expressions can use literals, variables, and expressions of various types, for example: double y; byte x; y = x + 5 ; This example adds the byte variable x to the int literal 5 and assigns the result to the double variable y. In Java, as in the C language, type conversions when evaluating expressions can be performed automatically or using a type cast operator. However, the rules for type casting are slightly different from the rules of the C language, and are generally more strict than in the C language. When performing an assignment operation, the type conversion occurs automatically if expanding transformation(widening conversion) and two types are compatible. Expanding transformations are transformations byte® short® int® long® float® double. For widening conversions, numeric types, including integer and floating-point, are compatible with each other. However, numeric types are not compatible with char and boolean types. The types char and boolean are also incompatible with each other. Java also performs automatic type conversion when storing a literal integer constant (which defaults to int) in a variable of type byte, short, or long (however, if the literal has a value outside the range of valid values ​​for that type, an error message is issued: possible loss of accuracy). If the conversion is a narrowing conversion, that is, a byte ¬ short ¬ char ¬ int ¬ long ¬ float ¬ double conversion is performed, then such a conversion can lead to loss of precision of the number or to its distortion. Therefore, during narrowing conversions, when compiling a program, a diagnostic message about type incompatibility is displayed and class files are not created. This message will also be issued if you try to convert an expression of type byte or short into a variable of type char . If it is still necessary to perform such conversions, the type cast operation is used, which has the following format: ( type-conversion) meaning, Where type-conversion determines the type to which the given data must be converted meaning, for example, as a result of executing the operators: byte x = 71 ; char symbol = (char ) x; the symbol variable will receive the value " G ". If a floating-point value is assigned to an integer type, then (if the floating-point value has a fractional part) an explicit type conversion also occurs truncation(truncation) numbers. So, as a result of executing the operator int x = (int) 77.85; variable x will get the value 77 . If the assigned value is outside the range type-conversion , then the result of the transformation will be the remainder of dividing the value by the modulus of the range of the assigned type (for numbers of type byte, the modulus of the range will be equal to 256, for short – 65536, for int – 4294967296 and for long – 18446744073709551616). For example, as a result of executing the operator byte x = (byte ) 514 ; the variable x will receive the value 2. When converting integers or real numbers to char data, the conversion to character occurs if the original number is in the range 0 to 127, otherwise the character is given the value "?". When performing arithmetic and bitwise conversions, all byte and short values, as well as char, are expanded to int, (with the numeric value of the character code used in the calculations for char) then, if at least one operand is of type long, the type of the integer expression is expanded to long. If one of the operands is of type float, then the type of the full expression is expanded to float, and if one of the operands is of type double, then the type of the result is double. So, if the variables byte a, c; short b; then in the expression a + b* c – 15 L + 1.5F + 1.08 - 10; first, before calculating a + b*c, the values ​​of the variables will be expanded to int, then, since the constant 15 is of type long, the result of the calculation will be expanded to long before subtraction. After that, since literal 1.5 is of type float, before adding with this literal, the result of evaluating a + b*c – 15L will be expanded to float . Before performing the addition on the number 1.08, the result of the previous calculations will be expanded to double (since real constants are of type double by default) and finally, before the last addition is performed, the literal 10 (default int) will be expanded to double. Thus, the result of evaluating the expression will be of type double . Automatic type extensions (especially short and byte to int extensions) can cause poorly recognized errors at compile time. For example, in the operators: byte x = 30 , y = 5 ; x = x + y; The values ​​of the variables x and y will be expanded to int before the addition is performed, and then an error message will be thrown when attempting to assign the result of an int to a byte variable. To avoid this, you must use an explicit type conversion in the second operator: x = (byte) (x + y) ; The expression x + y must be enclosed in parentheses because the precedence of the type cast operation enclosed in parentheses is higher than the priority of the addition operation. By the way, if you write the second operator in the form: x += y; then there will be no error message. Link to first

    Logical operators only work with operands of type boolean. All Boolean operators with two operands combine two Boolean values ​​to form a resulting Boolean value. Don't confuse with .

    Logical Operators Table in Java

    Logical operators & , | , ^ apply to values ​​of type boolean in exactly the same way as in relation to the bits of integer values. Logical operator ! inverts (reverses) a Boolean state: !true == false And !false == true.

    Table. Results of executing logical operators

    ABA | BA&BA^B!A
    falsefalsefalsefalsefalsetrue
    truefalsetruefalsetruefalse
    falsetruetruefalsetruetrue
    truetruetruetruefalsefalse

    Shortcut Logical Operators

    In addition to standard operators AND (&) And OR (|) there are shortcut operators && And || .

    If you look at the table, you can see that the result of executing the operator OR equals true true, regardless of the value of operand B. Similarly, the result of executing the operator AND equals false when the value of operand A is false, regardless of the value of operand B. It turns out that we do not need to calculate the value of the second operand if the result can already be determined from the first operand. This becomes convenient in cases where the value of the right operand depends on the value of the left one.

    Consider the following example. Let's say we introduced a rule - to feed or not to feed the cat depending on the number of mice caught per week. Moreover, the number of mice depends on the weight of the cat. The bigger the cat, the more mice it must catch.

    The cat, who read the conditions of the problem, was offended by me. He said that I was behind the times, and this is the 21st century - mice can be caught using mousetraps. I had to explain to him that this was just a problem, and not an example from my personal life.

    Int mouse; // number of mice int weight; // weight of the cat in grams mouse = 5; weight = 4500; if (mouse != 0 & weight / mouse< 1000) { mInfoTextView.setText("Можно кормить кота"); }

    If you run the program, the example will work without problems - five mice a week is enough to pamper your cat with a delicious breakfast. If he catches four mice, then problems will begin with the cat's nutrition, but not with the program - it will work, it just will not display a message about permission to feed the parasite.

    Now let's take an extreme case. The cat got lazy and didn’t catch a single mouse. Variable value mouse will be equal to 0, and the expression contains a division operator. But you can’t divide by 0 and our program will close with an error. It would seem that we have provided an option with 0, but Java evaluates both expressions mouse != 0 And weight/mouse< 1000 , despite the fact that already in the first expression it returns false.

    Let's rewrite the condition as follows (add just one character):

    If (mouse != 0 && weight / mouse< 1000) { mInfoTextView.setText("Можно кормить кота"); }

    Now the program works without crashing. Once Java saw that the first expression returned false, then the second division expression is simply ignored.

    Operator shortcuts AND And OR commonly used in situations where Boolean logic operators are required, and their single-character relatives are used for bitwise operations.

    Ternary operator

    Java also has a special ternary conditional operator that can replace certain types of operators if-then-else is the operator ?:

    The ternary operator uses three operands. The expression is written in the following form:

    BooleanCondition? expression1: expression2

    If booleanCondition equals true, then it is calculated expression1 and its result becomes the result of executing the entire statement. If booleanCondition equals false, then it is calculated expression2, and its value becomes the result of the operator. Both operands expression1 And expression2 must return a value of the same (or compatible) type.

    Let's consider an example in which the variable absval the absolute value of the variable is assigned val.

    Int absval,val; val = 5; absval = val< 0 ? -val: val; // выводим число mInfoTextView.setText("" + absval); val = -5; absval = val < 0 ? -val: val; mInfoTextView.setText("" + absval);

    Variable absval the value of the variable will be assigned val, if the value is greater than or equal to zero (second part of the expression). If the variable value val negative, then the variable absval the value of the variable is assigned, taken with a minus sign; as a result, minus by minus will give a plus, that is, a positive value. Let's rewrite the code using if-else:

    If(val< 0) absval = -val; else absval = val;

    You can see another example with the ternary operator.

    Short-circuit logical operators && and || are intended for logical AND (AND) and OR (OR) operations on expressions of type boolean. Note that there is no shortcut logical operator for the XOR (exclusive OR) operation.

    The shortened logical operators are similar to the & and | operators, but they are used differently only to expressions of type boolean and never apply to integral types. However, && and || have a remarkable property: they shorten the evaluation of an expression if the result can be deduced from part of the expression (I will explain this with examples a little later). Because of this property, the && and || operators widely used for handling null expressions. They also help increase the effectiveness of the overall program.

    The shortening property follows directly from the differences between &&/|| and &/|: The last pair of operators must take the values ​​of the left and right operators as input, while for the first pair of operators it is sometimes enough to know the value of only the left operand to return the value of the entire expression. This behavior of shortened logical operators is based on two mathematical rules of the logical truth table:

    • an expression with an AND operator is false if the value of at least one of its operands is false;
    • An expression with an OR operator is true if at least one of its operands is true.
    In other words:
    • false AND X = false
    • true OR X = true
    That is, if the left operand of an AND expression is false, then the entire expression is false, regardless of the value of the right operand. That is, if the left operand is false, there is no need to calculate the value of the right operand. Likewise, if the left operand of an OR expression is true, then the entire expression is true, regardless of the value of the right operand, which therefore we do not need to evaluate.

    Let's look at some example code that prints a String message if the string is non-null and more than 20 characters long:

    1. if ((s != null) && (s.length() > 20)) (
    2. System.out.println(s);
    3. }

    The same task can be coded differently:

    1. if (s != null) (
    2. if (s.length() > 20) (
    3. System.out.println(s);
    4. }
    5. }

    If the string s were null, then we would get a NullPointerException when calling the s.length() method. In neither of the two code examples, however, does this situation arise. In particular, in the second example, s.length() is not called when s = null due to the use of the shortened && operator. If the test (s!=null) returned false (false), that is, s is a non-existent string, then the entire expression is guaranteed to be false. This means that there is no need to calculate the value of the second operand, that is, the expression (s.length()>20) .

    However, these operators have side effects. For example, if the right operand is an expression that performs some operation, then when using shortened operators, this operation may fail if the left operand is false.

    Let's look at an example:
    // first example 1. int val = (int)(2 * Math.random()); 2. boolean test = (val == 0) || (++val == 2); 3. System.out.println(“test = “ + test + “\nval = “ + val); // second example 1. int val = (int)(2 * Math.random()); 2. boolean test = (val == 0)|(++val == 2); 3. System.out.println(“test = “ + test + “\nval = “ + val);
    The first example will sometimes print this:
    test = true
    val = 0

    And sometimes this:
    test = true
    val = 2

    The second example will sometimes print this:
    test = true
    val = 1

    And sometimes this:
    test = true
    val = 2

    Here's the thing. If val is 0, then the second operand (++val) will never be evaluated, meaning val will remain zero. If initially val is equal to one, then as a result this variable will be incremented and we will see val = 2. In the second example, when using Not shortened operators, the increment is always performed and the result will always be either 1 or 2 depending on the random value chosen in the first step. In both examples, the variable test evaluates to true because either val = 0 or val = 1 and is incremented to the value 2.

    Let's summarize the information about the shortened && and || operators:

    • They apply to boolean operands;
    • They evaluate the value of the right operand only if the result cannot be calculated from the value of the left operand:
      • false AND X = false
      • true OR X = true

    Most operations on primitive types are performed not using methods, but using special symbols called operation sign.

    Assignment operator

    Assigning a variable the value of a constant, another variable, or an expression (variables and/or constants separated by operator signs) is called assignment operation and is indicated by the sign " = ", for example: x = 3; y = x; z = x; In Java, it is possible to use the assignment operator multiple times in one expression, for example: x1 = x2 = x3 = 0 ; This operation is performed from right to left, i.e. first to the variable x3 is assigned the value 0, then the variable x2 is assigned the value of the variable x3 (0), and finally the variable x1 is assigned the value of the variable x2 (0). The signs of operations whose arguments are numbers are divided into two categories: unary(unary) signs of operations with one argument and binary(binary) with two arguments.

    Unary operations

    The following unary operators are defined in Java:
    • unary minus " - " – changes the sign of a number or expression to the opposite;
    • unary plus " + " – does not perform any actions on a number or expression;
    • bitwise complement "~" (for integers only) – inverts all bits of the number field (changes 0 to 1 and 1 to 0);
    • increment "++" (for integers only) – increases the value of the variable by 1;
    • decrement " -- " (for integers only) – decreases the value of the variable by 1.
    Examples of unary operations " + " and " - ": int i = 3 , j, k; j= - i; // j = -3 k = + i; // k = 3 Example of bitwise complement operation: int a = 15 ; int b; b = ~a; // b = -16 Numbers a and b are numbers of type int , i.e. are represented internally by the computer as signed binary integers of length 32 bits, so the binary representation of numbers a and b would look like this: a = 00000000 00000000 00000000 00001111 b = 11111111 11111111 11111111 11110000 As you can see from this representation, all zero bits in number a are changed to one bits in b, and the one bits in a are changed to zero bits. The decimal representation of b is –16. Increment and decrement operation signs can be placed either before or after the variable. These options are named accordingly prefix And postfix recording these transactions. The operator sign in prefix notation returns the value of its operand after expression evaluation. In postfix notation, the operation sign at first returns the value of its operand and only after that calculates the increment or decrement, for example: int x = 1, y, z; y = ++x; z= x++ ; The variable y will be assigned the value 2 because first the value of x will be incremented by 1 and then the result will be assigned to the variable y . The variable z will be assigned the value 1 because first the variable z will be assigned a value and then the value of x will be incremented by 1 . In both cases, the new value of x will be 2. It should be noted that in Java, unlike the C language, decrement and increment operations can also be applied to real variables (type float and double). Binary Operation Signs are divided into operations with a numerical result and comparison operations, the result of which is a Boolean value.

    Arithmetic binary operations

    Java defines the following arithmetic binary operations:
    • addition "+";
    • subtraction " - ";
    • multiplication " * ";
    • division "/";
    • calculating the remainder of the division of integers "%" (returns the remainder of the division of the first number by the second, and the result will have the same sign as the dividend), for example, the result of the operation 5%3 will be equal to 2, and the result of the operation (-7) %(-4) will be equal to -3. In Java, the operation can also be used for real variables (type float or double).
    Examples of binary arithmetic operations: int x = 7 , x1, x2, x3, x4, x5; x1 = x + 10 ; // x1 = 17 x2 = x – 8 ; // x2 = -1 x3 = x2 * x; // x3 = -7 x4 = x/ 4 ; // x4 = 1 (when dividing integers // fractional part is discarded) x5 = x% 4 // x5 = 3 (division remainder// 7 by 4)

    Bitwise operations

    • Bitwise operations treat raw numeric values ​​as fields of bits and perform the following operations on them:
    • setting bit in i The th position of the result field is 1 if both bits are in i The th positions of the operands are equal to 1, or 0 otherwise – bitwise AND ("& ");
    • setting bit in i The th position of the result field is 1 if at least one bit in i th positions of the operands is equal to 1, or 0 otherwise – bitwise OR (" | ");
    • setting bit in i The th position of the result field is 1 if the bits are in i-th positions of the operands are not equal to each other, or at 0 otherwise – bitwise exclusive OR (" ^ ");
    • shift to the left of the bits of the field of the first operand by the number of bits determined by the second operand (the sign bit of the number does not change) - bitwise shift to the left taking into account the sign "<< ";
    • right shift of the bits of the first operand field by the number of bits determined by the second operand (the sign bit of the number does not change) – bitwise shift to the right, taking into account the " >> " sign;
    • shift to the right of the bits of the field of the first operand by the number of bits determined by the second operand (the sign bit of the number is also shifted) - bitwise shift to the right without taking into account the " >>> " sign.
    Examples of bitwise operations:
    1. Bitwise AND

      int x = 112 ; int y = 94 ; int z; z = x & y; // z=80: 00000000 00000000 00000000 01010000
    2. Bitwise OR

      int x = 112 ; // x: 00000000 00000000 00000000 01110000 int y = 94 ; // y: 00000000 00000000 00000000 01011110 int z; z = x | y; // z = 126: 00000000 00000000 00000000 01111110
    3. Bitwise exclusive OR

      int x = 112 ; // x: 00000000 00000000 00000000 01110000 int y = 94 ; // y: 00000000 00000000 00000000 01011110 int z; z = x^y; // z = 46: 00000000 00000000 00000000 00101110
    4. Left shift based on sign

      int x = 31 , z; // x: 00000000 00000000 00000000 00011111 z = x<< 2 ; // z = 124: 00000000 00000000 00000000 01111100
    5. Right shift with sign

      int x = - 17 , z; z = x >> 2 ; // z = -5: 11111111 11111111 11111111 11111011
    6. Right shift without taking into account sign

      int x = - 17 , z; // x: 11111111 11111111 11111111 11101111 z = x >>> 2 ; // z = 1073741819 // z: 00111111 11111111 11111111 11111011

    Combined operations

    In Java, for binary arithmetic operations you can use combined(composite) operator signs: identifier operation = expression This is equivalent to the following operation: identifier = identifier operation expression Examples:
    1. The expression x += b means x = x + b.
    2. The expression x -= b means x = x - b .
    3. The expression x *= b means x = x * b .
    4. The expression x /= b means x = x / b.
    5. The expression x %= b means x = x % b .
    6. The expression x &= b means x = x & b .
    7. The expression x |= b means x = x | b.
    8. The expression x ^= b means x = x ^ b .
    9. Expression x<<= b означает x = x << b .
    10. The expression x >>= b means x = x >> b .
    11. The expression x >>>= b means x = x >>> b .

    Comparison Operations

    Java defines the following comparison operators:
    • " == " (equal), " != " (not equal),
    • " > " (greater than), " >= " (greater than or equal to),
    • " < " (меньше) " <= " (меньше или равно)
    have two operands and return a boolean value corresponding to the result of the comparison ( false or true). Please note that when comparing two quantities for equality in Java, as in C and C++, the symbols " == " (two consecutive equal signs without a space), as opposed to the assignment operator, which uses the symbol " = ". Using the " = " symbol when comparing two values ​​either causes a compilation error or leads to an incorrect result. Examples of comparison operations: boolean isEqual, isNonEqual, isGreater, isGreaterOrEqual, isLess, isLessOrEqual; int x1 = 5, x2 = 5, x3 = 3, x4 = 7; isEqual = x1 == x2; // isEqual = true isNonEqual = x1 != x2; // isNonEqual = false isGreater = x1 > x3; // isGreater = true // isGreaterOrEqual = true isGreaterOrEqual = x2 >= x3; isLess = x3< x1; // isLess = true isLessOrEqual = x1 <= x3; // isLessOrEqual = false

    Boolean operations

    Boolean operations are performed on Boolean variables and their result is also a value of type boolean. The following Boolean operations are defined in Java:
    • negation "!" – replacing false with true, or vice versa;
    • AND operation "&" – the result is true only if both operands are true, otherwise the result is false;
    • OR operation "|" – the result is true only if at least one of the operands is true, otherwise the result is false.
    • exclusive OR operation "^" – the result is true only if the operands are not equal to each other, otherwise the result is false.
    The operations " & ", " | " and " ^ " can, as well as the corresponding bitwise operations, be used in compound assignment operations: " &= ", " |= " and " ^= " In addition, the operations " = " are applicable to Boolean operands = " (equal) and " != " (not equal). As you can see from the definition of the OR and AND operators, the OR operation results in the result true when the first operand is true, regardless of the value of the second operand, and the AND operation results in the result false when the first operand is false, regardless of the value of the second operand. Java defines two more Boolean operators: second versions of the Boolean AND and OR operators, known as short-circuit logical operators: short-AND "&&" and short-circuit OR "||". When using these operations, the second operand will not be evaluated at all, which is useful in cases where the correct functioning of the right operand depends on whether the left operand is true or false . Examples of Boolean operations: boolean isInRange, isValid, isNotValid, isEqual, isNotEqual; int x = 8 ; isInRange = x > 0 && x< 5 ; // isInRange = false isValid = x >0 || x > 5 ; // isValid = true isNotValid = ! isValid; // isNotValid = false isEqual = isInRange == isValid; // isEqual = false // isNotEqual = true isNotEqual = isInRange != isValid

    Conditional operation

    The conditional operation is written in the form expression-1?expression-2:expression-3. In this case, the expression expression-1 is first evaluated, which should give a Boolean value, and then, if expression-1 is true, expression-2 is evaluated and returned as the result of the operation, or (if expression-1 is false), it is evaluated and , as a result of the operation, expression-3 is returned. Example of a conditional operation: x= n> 1 ? 0 : 1 ; The variable x will be assigned the value 0 if n>1 (the expression n>1 is true) or 1 if n≤1 (the expression n>1 is false).

    Operation seniority

    Operations in expressions are performed from left to right, however, in accordance with their priority. So the multiplication operations in the expression y = x + z* 5; will be executed before the addition operation because the priority of the multiplication operation is higher than the priority of the addition operation. The priorities of operations (in order of decreasing priority) in Java are given in table. 1.
    Parentheses increase the precedence of the operations that are inside them. So, if you insert parentheses into the above expression: y = (x + z) * 5 ; then the addition operation will be performed first, and then the multiplication operation. Sometimes parentheses are used simply to make an expression more readable, for example: (x > 1 ) && (x<= 5 ) ;

    Conversion and casting when performing operations

    Assignment operations and arithmetic expressions can use literals, variables, and expressions of various types, for example: double y; byte x; y = x + 5 ; This example adds the byte variable x to the int literal 5 and assigns the result to the double variable y. In Java, as in the C language, type conversions when evaluating expressions can be performed automatically or using a type cast operator. However, the rules for type casting are slightly different from the rules of the C language, and are generally more strict than in the C language. When performing an assignment operation, the type conversion occurs automatically if expanding transformation(widening conversion) and two types are compatible. Expanding transformations are transformations byte® short® int® long® float® double. For widening conversions, numeric types, including integer and floating-point, are compatible with each other. However, numeric types are not compatible with char and boolean types. The types char and boolean are also incompatible with each other. Java also performs automatic type conversion when storing a literal integer constant (which defaults to int) in a variable of type byte, short, or long (however, if the literal has a value outside the range of valid values ​​for that type, an error message is issued: possible loss of accuracy). If the conversion is a narrowing conversion, that is, a byte ¬ short ¬ char ¬ int ¬ long ¬ float ¬ double conversion is performed, then such a conversion can lead to loss of precision of the number or to its distortion. Therefore, during narrowing conversions, when compiling a program, a diagnostic message about type incompatibility is displayed and class files are not created. This message will also be issued if you try to convert an expression of type byte or short into a variable of type char . If it is still necessary to perform such conversions, the type cast operation is used, which has the following format: ( type-conversion) meaning, Where type-conversion determines the type to which the given data must be converted meaning, for example, as a result of executing the operators: byte x = 71 ; char symbol = (char ) x; the symbol variable will receive the value " G ". If a floating-point value is assigned to an integer type, then (if the floating-point value has a fractional part) an explicit type conversion also occurs truncation(truncation) numbers. So, as a result of executing the operator int x = (int) 77.85; variable x will get the value 77 . If the assigned value is outside the range type-conversion , then the result of the transformation will be the remainder of dividing the value by the modulus of the range of the assigned type (for numbers of type byte, the modulus of the range will be equal to 256, for short – 65536, for int – 4294967296 and for long – 18446744073709551616). For example, as a result of executing the operator byte x = (byte ) 514 ; the variable x will receive the value 2. When converting integers or real numbers to char data, the conversion to character occurs if the original number is in the range 0 to 127, otherwise the character is given the value "?". When performing arithmetic and bitwise conversions, all byte and short values, as well as char, are expanded to int, (with the numeric value of the character code used in the calculations for char) then, if at least one operand is of type long, the type of the integer expression is expanded to long. If one of the operands is of type float, then the type of the full expression is expanded to float, and if one of the operands is of type double, then the type of the result is double. So, if the variables byte a, c; short b; then in the expression a + b* c – 15 L + 1.5F + 1.08 - 10; first, before calculating a + b*c, the values ​​of the variables will be expanded to int, then, since the constant 15 is of type long, the result of the calculation will be expanded to long before subtraction. After that, since literal 1.5 is of type float, before adding with this literal, the result of evaluating a + b*c – 15L will be expanded to float . Before performing the addition on the number 1.08, the result of the previous calculations will be expanded to double (since real constants are of type double by default) and finally, before the last addition is performed, the literal 10 (default int) will be expanded to double. Thus, the result of evaluating the expression will be of type double . Automatic type extensions (especially short and byte to int extensions) can cause poorly recognized errors at compile time. For example, in the operators: byte x = 30 , y = 5 ; x = x + y; The values ​​of the variables x and y will be expanded to int before the addition is performed, and then an error message will be thrown when attempting to assign the result of an int to a byte variable. To avoid this, you must use an explicit type conversion in the second operator: x = (byte) (x + y) ; The expression x + y must be enclosed in parentheses because the precedence of the type cast operation enclosed in parentheses is higher than the priority of the addition operation. By the way, if you write the second operator in the form: x += y; then there will be no error message. Link to first