Bigdecimal from double
Summary
- Rule ID:
BIGDECIMAL_FROM_DOUBLE - Name: BigDecimal from double
- Description: Reports
BigDecimalconstructor calls that takedoublebecause they can introduce precision surprises. - Annotation policy:
@Suppress/@SuppressWarningsare not supported; only JSpecify annotations are recognized for annotation-driven semantics, and non-JSpecify annotations do not change behavior.
Motivation
Using new BigDecimal(double) captures binary floating-point approximation instead of the intended decimal value. This can cause subtle rounding and comparison bugs in financial or precision-sensitive code.
What it detects
- Constructor calls to
java/math/BigDecimal.<init>(D)V. - Constructor calls to
java/math/BigDecimal.<init>(DLjava/math/MathContext;)V. - Findings on analysis-target classes only.
What it does NOT detect
BigDecimal.valueOf(double)calls.- String-based constructors such as
new BigDecimal("0.1"). - Suppression via annotations (
@Suppress,@SuppressWarnings) is not supported. - Non-JSpecify annotations do not affect rule behavior.
Examples (TP/TN/Edge)
True Positive
True Negative
import java.math.BigDecimal;
class ClassB {
BigDecimal MethodY() {
return BigDecimal.valueOf(0.1d);
}
}
Edge Case
import java.math.BigDecimal;
import java.math.MathContext;
class ClassC {
BigDecimal MethodZ(double varOne) {
return new BigDecimal(varOne, MathContext.DECIMAL64);
}
}
Output
- Message: "BigDecimal constructed from double can lose precision. Use BigDecimal.valueOf(double) or a decimal string constructor."
- Location: the
BigDecimalconstructor call site.
Performance considerations
- Expected linear scan over extracted call sites per method.
- No control-flow fixpoint analysis is required.
Acceptance criteria
- Reports a finding for each
BigDecimalconstructor call that acceptsdouble. - Does not report
BigDecimal.valueOf(double)or string constructors. - Emits the actionable message defined in Output.
- Applies only to analysis-target classes.
- Applies annotation policy exactly as stated in Summary.