An issue is raised when an integer value (int or long) is implicitly converted to a floating-point type (float or double) in a context where precision loss is possible.

Why is this an issue?

Java allows implicit widening conversions from integer types to floating-point types. While these conversions are safe in terms of range (the floating-point type can represent larger magnitudes), they can silently lose precision.

Floating-point types use binary representation with limited precision:

When you convert larger integer values to these types, the least significant digits may be rounded, resulting in a value that differs from the original integer. This happens silently because Java permits the conversion without requiring a cast.

For example, converting the int value 16777217 to float results in 16777216.0 - the original value cannot be represented exactly and gets rounded to the nearest representable value.

This is particularly problematic when:

Making these conversions explicit with a cast documents that you are aware of potential precision loss and helps prevent accidental data corruption.

What is the potential impact?

Data Corruption

Precision loss in conversions can lead to incorrect values being stored or processed. When working with identifiers, database keys, or financial calculations, even small rounding errors can have serious consequences.

Logic Errors

Code that compares converted values for equality may produce unexpected results. A value converted to float and back may not equal the original integer, breaking assumptions in your logic.

Debugging Difficulty

Silent precision loss is hard to detect and diagnose. The code compiles without warnings, and the loss may only manifest under specific input values, making bugs intermittent and difficult to reproduce.

How to fix it

When converting int to float, use an explicit cast to document awareness of potential precision loss for large values (beyond ±16,777,216).

Code examples

Noncompliant code example

public class DataProcessor {
    public void processValue(int id) {
        float floatId = id; // Noncompliant - implicit conversion may lose precision
        System.out.println(floatId);
    }

    public float calculateRatio(int numerator, int denominator) {
        float ratio = numerator / denominator; // Noncompliant - implicit conversion
        return ratio;
    }
}

Compliant solution

public class DataProcessor {
    public void processValue(int id) {
        float floatId = (float) id; // Explicit cast shows intent
        System.out.println(floatId);
    }

    public float calculateRatio(int numerator, int denominator) {
        float ratio = (float) (numerator / denominator); // Clear conversion
        return ratio;
    }
}

Resources

Documentation