JB Header

Java Arithmetic, Relational and Logical Operators

Introduction Operators are the symbols which perform calculations and comparisons, such as +, > and &&. This tutorial covers the three groups you will use most - Java's arithmetic, relational and logical operators. We will start with the arithmetic operators, and the behaviour of integer division and the remainder operator. We will then look at the relational operators, which compare values, and the special case of comparing objects. Next we will combine conditions with the logical operators, and see how short-circuit evaluation works. Lastly, we will put them together in a small example.

(Note - The remaining operators are covered in Bitwise and Shift OperatorsClick to read tutorial: Java Bitwise and Shift Operators with Examples and Assignment, Increment/Decrement and Ternary OperatorsClick to read tutorial: Java Assignment, Increment/Decrement and Ternary Operators.) Arithmetic operators
  • + addition (also joins strings), - subtraction, * multiplication, / division, % remainder (modulus).
  • The unary operators + and - work on a single value - -x negates x.
Arithmetic operators
//Arithmetic.java
public class Arithmetic {
  public static void main(String[] args) {
    int a = 17, b = 5;
    System.out.println("a + b = " + (a + b));
    System.out.println("a - b = " + (a - b));
    System.out.println("a * b = " + (a * b));
    System.out.println("a / b = " + (a / b));
    System.out.println("a % b = " + (a % b));
    System.out.println("17.0 / 5 = " + (17.0 / 5));
    System.out.println("-17 % 5 = " + (-17 % 5));
    System.out.println("5.5 % 2 = " + (5.5 % 2));
    System.out.println("1.0 / 0 = " + (1.0 / 0) + ", 0.0 / 0 = " + (0.0 / 0));
    System.out.println("Is 17 even? " + (a % 2 == 0));
    System.out.println("Last digit of 4096 = " + (4096 % 10));
  }
}
 OUTPUT of the above code
a + b = 22
a - b = 12
a * b = 85
a / b = 3
a % b = 2
17.0 / 5 = 3.4
-17 % 5 = -2
5.5 % 2 = 1.5
1.0 / 0 = Infinity, 0.0 / 0 = NaN
Is 17 even? false
Last digit of 4096 = 6
Explanation of the code
  • Integer division: 17 / 5 is 3. When both values are integers, the result is an integer and the fractional part is dropped. Make one value a double - 17.0 / 5 - to get 3.4. (The rules are explained in Type Conversion and CastingClick to read tutorial: Type Conversion and Casting in Java with Examples.)
  • Remainder: 17 % 5 is 2, what is left after dividing. The result has the sign of the left value, so -17 % 5 is -2. % works with floating-point numbers too.
  • % is very useful: n % 2 == 0 tests whether a number is even, and n % 10 gives its last digit.
  • Dividing a floating-point number by zero gives Infinity, and 0.0 / 0 gives NaN (Not a Number). Dividing an integer by zero, however, throws an ArithmeticException.
Relational (comparison) operators Relational operators compare two values and give a boolean result - true or false.
  • == equal to, != not equal to
  • > greater than, < less than, >= greater than or equal to, <= less than or equal to
Relational operators
//Relational.java
public class Relational {
  public static void main(String[] args) {
    int age = 20;
    System.out.println("age == 20 : " + (age == 20));
    System.out.println("age != 18 : " + (age != 18));
    System.out.println("age > 21  : " + (age > 21));
    System.out.println("age <= 20 : " + (age <= 20));
    System.out.println("'a' < 'b' : " + ('a' < 'b'));

    System.out.println("0.1 + 0.2 == 0.3 : " + (0.1 + 0.2 == 0.3));
    System.out.println("close enough     : " + (Math.abs((0.1 + 0.2) - 0.3) < 1e-9));

    String s1 = "Java";
    String s2 = new String("Java");
    System.out.println("s1 == s2      : " + (s1 == s2));
    System.out.println("s1.equals(s2) : " + s1.equals(s2));
  }
}
 OUTPUT of the above code
age == 20 : true
age != 18 : true
age > 21  : false
age <= 20 : true
'a' < 'b' : true
0.1 + 0.2 == 0.3 : false
close enough     : true
s1 == s2      : false
s1.equals(s2) : true
Explanation of the code
  • Characters are compared by their Unicode numbers, so 'a' < 'b' is true.
  • 0.1 + 0.2 == 0.3 is false because of floating-point rounding. Compare floating-point values by checking that their difference is tiny, instead of using ==.
  • For objects, == checks whether two references point to the same object, not whether the objects have the same content. s1 and s2 hold the same text but are different objects, so == is false. Use equals() to compare contents. This is explained fully in == vs equals() vs compareTo()Click to read tutorial: Java String Comparison: == vs equals() vs compareTo().
  • Do not confuse == (compare) with = (assign).
Logical operators Logical operators combine boolean values -
  • && (AND) - true only if both sides are true.
  • || (OR) - true if at least one side is true.
  • ! (NOT) - reverses a value: !true is false.
  • ^ (XOR, exclusive OR) - true if exactly one side is true.
Logical operators
//Logical.java
public class Logical {
  public static void main(String[] args) {
    int age = 25;
    boolean hasTicket = true;
    boolean isMember = false;

    System.out.println("Adult with ticket : " + (age >= 18 && hasTicket));
    System.out.println("Ticket or member  : " + (hasTicket || isMember));
    System.out.println("Not a member      : " + !isMember);
    System.out.println("Exactly one       : " + (hasTicket ^ isMember));
    System.out.println("Age 13 to 19      : " + (age >= 13 && age <= 19));
  }
}
 OUTPUT of the above code
Adult with ticket : true
Ticket or member  : true
Not a member      : true
Exactly one       : true
Age 13 to 19      : false
Note - To check that a value is in a range, compare it twice and join the results with &&. Writing 13 <= age <= 19, as in mathematics, does not compile in Java.
Short-circuit evaluation && and || are short-circuit operators - they skip the right-hand side when the left-hand side already decides the result. For &&, if the left side is false, the result must be false; for ||, if the left side is true, the result must be true. This lets you guard a risky check with a safe one -
Short-circuit evaluation
//ShortCircuit.java
public class ShortCircuit {
  static boolean check(String label, boolean value) {
    System.out.println("  evaluating " + label);
    return value;
  }

  public static void main(String[] args) {
    System.out.println("false && ... :");
    boolean r1 = check("left", false) && check("right", true);
    System.out.println("true || ... :");
    boolean r2 = check("left", true) || check("right", false);
    System.out.println("false & ... (non-short-circuit):");
    boolean r3 = check("left", false) & check("right", true);

    String name = null;
    if (name != null && name.length() > 3) {
      System.out.println("Long name");
    } else {
      System.out.println("No name, and no NullPointerException");
    }
  }
}
 OUTPUT of the above code
false && ... :
  evaluating left
true || ... :
  evaluating left
false & ... (non-short-circuit):
  evaluating left
  evaluating right
No name, and no NullPointerException
Explanation of the code
  • With && and ||, the right-hand check() was never called, because the left side decided the result.
  • The single & (and single |) also work on booleans, but always evaluate both sides. They are rarely what you want for conditions.
  • name != null && name.length() > 3 is safe: when name is null, name.length() is never called, which avoids a NullPointerException. The order of the two checks matters.
Putting it together - a leap year check A year is a leap year if it is divisible by 4 but not by 100, or if it is divisible by 400. This rule uses all three groups of operators.
A leap year check using arithmetic, relational and logical operators
//LeapYear.java
public class LeapYear {
  static boolean isLeapYear(int year) {
    return (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;
  }

  public static void main(String[] args) {
    int[] years = {1900, 2000, 2024, 2026};
    for (int year : years) {
      System.out.println(year + " is a leap year: " + isLeapYear(year));
    }
  }
}
 OUTPUT of the above code
1900 is a leap year: false
2000 is a leap year: true
2024 is a leap year: true
2026 is a leap year: false
Summary In this tutorial we first used the arithmetic operators, and saw that integer division drops the fractional part, that % gives the remainder, and how division by zero behaves. We then compared values with the relational operators, saw why == is unreliable for floating-point numbers, and that it compares references for objects. Next we combined conditions with the logical operators &&, ||, ! and ^, and saw how short-circuit evaluation can guard against a NullPointerException. Lastly, we combined all three groups in a leap year check. In the next tutorial, we will look at the bitwise and shift operatorsClick to read tutorial: Java Bitwise and Shift Operators with Examples.