This rule raises an issue when methods that compare values for sorting or ordering purposes compare floating-point values using subtraction or simple relational operators (<, >, , >=) instead of dedicated comparison utilities designed for floating-point numbers.

In Java, this specifically applies to compareTo() methods (from the Comparable interface) and compare() methods (from the Comparator interface).

Why is this an issue?

Comparing floating-point values (single or double precision) using subtraction or simple comparison operators does not correctly handle special IEEE 754 values such as NaN (Not a Number) and negative zero (-0.0).

The IEEE 754 floating-point standard defines specific rules for these edge cases:

When you implement comparison using subtraction (e.g., converting the difference between two floating-point values to an integer result), several problems occur:

Using simple comparison operators like < or > also fails:

Standard library functions designed for floating-point comparison handle all these edge cases correctly. They impose a total ordering that treats:

This ensures that comparison methods satisfy the general contract required by comparison interfaces and comparator implementations.

In Java, use the Float.compare() and Double.compare() methods for proper floating-point comparison. These methods correctly implement the total ordering described above and satisfy the contracts of the Comparable interface and Comparator implementations.

What is the potential impact?

Using incorrect floating-point comparison can lead to several serious issues:

In Java, these requirements are formalized in the Comparable and Comparator contracts.

How to fix it

Replace subtraction-based comparison with Double.compare() or Float.compare(). These methods return a negative integer, zero, or positive integer as the first argument is less than, equal to, or greater than the second, while correctly handling all IEEE 754 special cases.

This fix always applies when floating-point values are compared in ordering methods. There is no scenario where subtraction-based comparison of float or double values in a compareTo() or compare() method is correct, because it silently mishandles NaN, negative zero, and values whose difference is smaller than 1.

This rule does not flag subtraction of integer types or floating-point comparisons outside of ordering methods.

If you believe the finding is a false positive, verify that the flagged expression genuinely involves float or double operands in a compareTo() or compare() method. If it does, the finding is not a false positive — the subtraction approach is always incorrect for these types in ordering contexts, even when the values happen to be well-bounded in practice.

Code examples

Noncompliant code example

class Position implements Comparable<Position> {
    private double latitude;
    private double longitude;

    @Override
    public int compareTo(Position other) {
        int latComparison = (int)(this.latitude - other.latitude); // Noncompliant
        if (latComparison != 0) {
            return latComparison;
        }
        return (int)(this.longitude - other.longitude); // Noncompliant
    }
}

Compliant solution

class Position implements Comparable<Position> {
    private double latitude;
    private double longitude;

    @Override
    public int compareTo(Position other) {
        int latComparison = Double.compare(this.latitude, other.latitude);
        if (latComparison != 0) {
            return latComparison;
        }
        return Double.compare(this.longitude, other.longitude);
    }
}

Resources

Documentation