Additive Binary Operators: +, – – Basic Elements, Primitive Data Types, and Operators

Additive Binary Operators: +, –

The addition operator + and the subtraction operator – behave as their names imply: They add and subtract values, respectively. The binary operator + also acts as string concatenation if any of its operands is a string (p. 67).

Additive operators have lower precedence than all the other arithmetic operators. Table 2.21 includes examples that show how precedence and associativity are used in arithmetic expression evaluation.

Table 2.21 Examples of Arithmetic Expression Evaluation

Numeric Promotions in Arithmetic Expressions

Unary numeric promotion is applied to the single operand of the unary arithmetic operators – and +. When a unary arithmetic operator is applied to an operand whose type is narrower than int, the operand is promoted to a value of type int, with the operation resulting in an int value. If the conditions for implicit narrowing conversion are not fulfilled (p. 56), assigning the int result to a variable of a narrower type will require a cast. This is demonstrated by the following example, where the byte operand b is promoted to an int in the expression (-b):

Click here to view code image

byte b = 3;           // int literal in range. Narrowing conversion.
b = (byte) -b;        // Cast required on assignment.

Binary numeric promotion is applied to operands of binary arithmetic operators. Its application leads to type promotion for the operands, as explained in §2.4, p. 49. The result is of the promoted type, which is always type int or wider. For the expression at (1) in Example 2.2, numeric promotions proceed as shown in Figure 2.4. Note the integer division performed in evaluating the subexpression (c / s).

Figure 2.4 Numeric Promotion in Arithmetic Expressions

Example 2.2 Numeric Promotion in Arithmetic Expressions

Click here to view code image

public class NumPromotion {
  public static void main(String[] args) {
    byte   b = 32;
    char   c = ‘z’;                              // Unicode value 122 (\u007a)
    short  s = 256;
    int    i = 10000;
    float  f = 3.5F;
    double d = 0.5;
    double v = (d * i) + (f * -b) – (c / s);     // (1) 4888.0D
    System.out.println(“Value of v: ” + v);
  }
}

Output from the program:

Value of v: 4888.0

In addition to the binary numeric promotions in arithmetic expression evaluation, the resulting value can undergo an implicit widening conversion if assigned to a variable. In the first two declaration statements that follow, only assignment conversions take place. Numeric promotions take place in the evaluation of the right-hand expression in the other declaration statements.

Click here to view code image

Byte   b = 10;       // Constant in range: narrowing and boxing on assignment.
Short  s = 20;       // Constant in range: narrowing and boxing on assignment.

char   c = ‘z’;      // 122 (\u007a)
int    i = s * b;    // Values in s and b promoted to int: unboxing, widening.
long   n = 20L + s;  // Value in s promoted to long: unboxing, widening.
float  r = s + c;    // Value in s is unboxed. This short value and the char
                     // value in c are promoted to int, followed by implicit
                     // widening conversion of int to float on assignment.
double d = r + i;    // Value in i promoted to float, followed by implicit
                     // widening conversion of float to double on assignment.

Binary numeric promotion for operands of binary operators implies that each operand of a binary operator is promoted to type int or a broader numeric type, if necessary. As with unary operators, care must be exercised in assigning the value resulting from applying a binary operator to operands of these types.

Click here to view code image

short h = 40;          // OK: int converted to short. Implicit narrowing.
h = h + 2;             // Error: cannot assign an int to short.

The value of the expression h + 2 is of type int. Although the result of the expression is in the range of short, this cannot be determined at compile time. The assignment requires a cast.

h = (short) (h + 2);   // OK

Notice that applying the cast operator (short) to the individual operands does not work:

Click here to view code image

h = (short) h + (short) 2;     // The resulting value should be cast.

Neither does the following approach, which results in a compile-time error:

Click here to view code image

h = (short) h + 2;             // The resulting value should be cast.

In this case, binary numeric promotion leads to an int value as the result of evaluating the expression on the right-hand side, and therefore, requires an additional cast to narrow it to a short value.