double
holds no precision, and is an approximation, a sum of (negative) powers of 2. Hence 3.10 might on output be 3.0999999785, an error which enlarges when summing or multiplying.
For holding a precision and being precise - as with financial software - BigDecimal is used.
BigDecimal amount = new BigDecimal("12.99"); // A precision of 2 digits.
BigDecimal base = new BigDecimal("4.33");
assert base.multiply(BigDecimal.valueOf(3)).compareTo(amount) == 0;
Unfortunately with BigDecimal normal math operators are not available, but in general it is not as unsafe as with double.