We are checking the quality of our code using Sonar, and Sonar found code which compares a float or double for equality with a constant value like this:
if (x == 0.0) { … }
The value the variable is compared with (0.0
) is constant, and in case the variable can be equal to this value, the value also isn't computed but only set via a constant. This is typically used to check whether a variable hasn't been set yet or is still at initialization state, e. g. -1.0
might be used for "not yet set" in cases where the value can only be positive.
So, since these values are never computed but only set from constants, the Sonar complaint is not useful for us. Only for computed values (or fractured ones which are not precisely representable as floats or doubles) a complaint about a test for equality makes sense.
The question I have now is: What is the best practice to change the code so that Sonar does not complain about this anymore?
I see several options:
- Extract the "test-for-unset" into a special test function; but that would only reduce the number of occurrences (to 1), not the issue in general.
- Mark the code for Sonar to ignore it with a special decorator. But we would like to avoid using such decorators.
- Hide the comparison behind sth like
(0.0 <= x && x <= 0.0)
or!(x != 0.0)
(which currently seems to be okay for Sonar). - Calling
Double.doubleToRawLongBits()
to compare the bits of the values like this:(Double.doubleToRawLongBits(x) != Double.doubleToRawLongBits(0.0))
. - Other ideas?
None of these solutions I really like and I thought, maybe, there is a better one out there I can't think of.
The best option here is to mark the issue as false positive and to leave a comment. This way the issue and associated technical debt will disappear from your SonarQube instance, without polluting your code with annotations.