S2111 should filter or downgrade minor cases

Rule java:S2111 flags any use of the BigDecimal(double) constructor because of the potential for hideously long (and inaccurate) numbers caused by inherent floating point imprecision. These are major bugs (used to be critical).

While the recommended replacements in the rule description (e.g., BigDecimal.valueOf() ) are probably the best approach overall, some “second-best” approaches are still getting flagged.

Java at some point (I think 1.5) added a constructor (double, MathContext) which lets you specify the precision and roundoff. Use of this constructor avoids the inaccuracy problem (assuming a reasonable value to the MathContext constructor). But SonarLint still flags:

image

(The blue squiggle is from SonarLint in CodeReady). It also flags the rule if the constructor call is followed by a call to setScale:

image

This is probably a “third-rate” solution because it could involve creating the long number and then fixing it, unless the compiler(s) optimize and just make the BigDecimal constant up front.

But either way, the situation in the rule description won’t occur here. So I would make exceptions to the rule for when 1) the (double, MathContext) constructor is used, and 2) the plain (double) constructor is chained with a setScale() method call. (Maybe there could be a separate smell rule for those cases since I agree they’re still “smelly.”)

(This is with SQ 8.6 but the current rule description (https://rules.sonarsource.com/java/RSPEC-2111) doesn’t mention anything about exceptions.)

(Also see S2111 should check for integer equivalence)