BigDecimal From Floating-Point Value

ID

java.bigdecimal_double

Severity

high

Remediation Complexity

medium

Remediation Risk

low

Remediation Effort

medium

Resource

Code Smell

Language

Java

Tags

reliability

Description

Reports new BigDecimal(…​) calls whose first argument is a double or float value — primitive or boxed, including the two-argument BigDecimal(double, MathContext) overload.

Constructing from a String, an int/long, or a BigInteger is exact and is not flagged, and neither is BigDecimal.valueOf(double).

Rationale

double and float are binary floating-point types: most decimal fractions have no exact binary representation, so the value stored is already an approximation before BigDecimal ever sees it. The constructed BigDecimal then carries that approximation forward at full precision, which is rarely what the caller intended.

double taxRate = 0.1;
BigDecimal rate = new BigDecimal(taxRate); // looks like 0.1, is actually
                                            // 0.1000000000000000055511151231257827021181583404541015625

Remediation

Use BigDecimal.valueOf(double), which converts through the value’s String representation and so avoids the extra binary-to-decimal drift, or construct directly from a String literal:

double taxRate = 0.1;
BigDecimal rate = BigDecimal.valueOf(taxRate); // exact for the printed value of taxRate

BigDecimal fixed = new BigDecimal("0.10");     // exact, no conversion needed

© 2026 Xygeni. All rights reserved