检查双精度的相等性和声纳问题

2022-09-03 12:51:05

我们正在使用Sonar检查代码的质量,Sonar找到了代码,该代码将浮点数或双精度的相等性与常量值进行比较,如下所示:

if (x == 0.0) { … }

与变量()进行比较的值是常量,如果变量可以等于此值,则该值也不会计算,而只能通过常量设置。这通常用于检查变量是否尚未设置或仍处于初始化状态,例如 可用于“尚未设置”,如果值只能为正数。0.0-1.0

因此,由于这些值从未计算过,而只是从常量设置,因此Sonar投诉对我们无用。只有对于计算值(或不能精确表示为浮点数或加倍值的断裂值),对相等性检验的抱怨才有意义。

我现在的问题是:更改代码以使Sonar不再抱怨这一点的最佳实践是什么?

我看到几个选项:

  1. 将“未设置测试”提取到特殊的测试函数中;但这只会减少发生次数(减少到1次),而不是一般问题。
  2. 标记Sonar的代码以使用特殊的装饰器忽略它。但我们希望避免使用这样的装饰器。
  3. 将比较隐藏在sth like or后面(目前对于Sonar来说似乎没问题)。(0.0 <= x && x <= 0.0)!(x != 0.0)
  4. 调用以比较值的位,如下所示:。Double.doubleToRawLongBits()(Double.doubleToRawLongBits(x) != Double.doubleToRawLongBits(0.0))
  5. 其他想法?

这些解决方案都不是我真正喜欢的,我想,也许,有一个更好的解决方案,我想不出。


答案 1

我会选择你的第二个选择:

标记Sonar的代码以使用特殊的装饰器忽略它。

不要成为静态代码分析工具的奴隶。他们并不完美,告诉他们闭嘴也没有错。在使用注释时,我的个人做法是包含注释来解释我为什么要使用它。@SuppressLint

也就是说,我会创建一个常量,这样代码就更加不言自明:

private static final double UNINITIALIZED = 0.0;
if (x == UNINITIALIZED) { … }

答案 2

这里最好的选择是将问题标记为误报并发表评论。这样,问题和相关的技术债务将从您的SonarQube实例中消失,而不会用注释污染您的代码。