CodeQL 文档

随机数的绝对值不正确

ID: java/abs-of-random
Kind: problem
Security severity: 
Severity: warning
Precision: medium
Tags:
   - reliability
   - maintainability
Query suites:
   - java-security-and-quality.qls

点击查看 CodeQL 存储库中的查询

Random.nextInt()(或 Random.nextLong())调用的结果使用 Math.abs 不能保证返回非负数。 Random.nextInt() 可以返回 Integer.MIN_VALUE,当将其传递给 Math.abs 时,结果为相同的值 Integer.MIN_VALUE。(由于 Java 中整数采用二进制补码表示,因此 Integer.MIN_VALUE 的正等价值无法用相同数量的位表示。) Random.nextLong() 的情况类似。

建议

如果需要非负随机整数,请改用 Random.nextInt(int),并使用 Integer.MAX_VALUE 作为其参数。可能返回的值不包括 Integer.MAX_VALUE 本身,但此解决方案可能足以满足大多数目的。

另一种解决方案是在将结果传递给 Math.abs 之前,如果 Random.nextInt() 为负数,则将其值加 1。此解决方案的优点是 0 与其他数字具有相同的概率。

示例

在以下示例中,如果 nextInt 返回 Integer.MIN_VALUE,则 mayBeNegativeInt 为负数。此示例展示了如何使用上面描述的两个解决方案,这意味着 positiveInt 始终被分配一个正数。

public static void main(String args[]) {
    Random r = new Random();

    // BAD: 'mayBeNegativeInt' is negative if
    // 'nextInt()' returns 'Integer.MIN_VALUE'.
    int mayBeNegativeInt = Math.abs(r.nextInt());

    // GOOD: 'nonNegativeInt' is always a value between 0 (inclusive)
    // and Integer.MAX_VALUE (exclusive).
    int nonNegativeInt = r.nextInt(Integer.MAX_VALUE);

    // GOOD: When 'nextInt' returns a negative number increment the returned value.
    int nextInt = r.nextInt();
    if(nextInt < 0)
        nextInt++;
    int nonNegativeInt = Math.abs(nextInt);
}

参考

  • ©GitHub, Inc.
  • 条款
  • 隐私