If you want 2 / 3 to result in 66.67, you need to multiply first, then divide and round to 2 decimal places:
BigDecimal totalPrep = BigDecimal.valueOf(2);
BigDecimal totalCase = BigDecimal.valueOf(3);
BigDecimal result = totalPrep.multiply(BigDecimal.valueOf(100))
.divide(totalCase, 2, RoundingMode.HALF_UP);
System.out.println(result); // prints: 66.67
That will calculate 2 * 100 = 200, then 200 / 3 = 66.67 (rounded)
When you divide first, you calculate 2 / 3 = 0.67 (rounded), then 0.67 * 100 = 67.00, which is obviously not what you want.
java - BigDecimal divide with a large number of decimal places - Stack Overflow
java - Rounding BigDecimal to *always* have two decimal places - Stack Overflow
round up to 2 decimal places in java? - Stack Overflow
Java's Bigdecimal.divide and rounding - Stack Overflow
How do I round a double to 2 decimal places in Java?
What is the difference between setScale and round(MathContext) on a BigDecimal?
How do I fix "ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result"?
I think that the RoundingMode you are looking for is HALF_EVEN. From the javadoc:
Rounding mode to round towards the "nearest neighbor" unless both neighbors are equidistant, in which case, round towards the even neighbor. Behaves as for ROUND_HALF_UP if the digit to the left of the discarded fraction is odd; behaves as for ROUND_HALF_DOWN if it's even. Note that this is the rounding mode that minimizes cumulative error when applied repeatedly over a sequence of calculations.
Here is a quick test case:
Use with AIBigDecimal a = new BigDecimal("10.12345");
BigDecimal b = new BigDecimal("10.12556");
a = a.setScale(2, RoundingMode.HALF_EVEN);
b = b.setScale(2, RoundingMode.HALF_EVEN);
System.out.println(a);
System.out.println(b);
Correctly prints:
Use with AI10.12
10.13
UPDATE:
setScale(int, int) has not been recommended since Java 1.5, when enums were first introduced, and was finally deprecated in Java 9. You should now use setScale(int, RoundingMode) e.g:
setScale(2, RoundingMode.HALF_EVEN)
Add 0.001 first to the number and then call setScale(2, RoundingMode.ROUND_HALF_UP)
Code example:
Use with AIpublic static void main(String[] args) {
BigDecimal a = new BigDecimal("10.12445").add(new BigDecimal("0.001"));
BigDecimal b = a.setScale(2, BigDecimal.ROUND_HALF_UP);
System.out.println(b);
}
Well this one works...
double roundOff = Math.round(a * 100.0) / 100.0;
Output is
123.14
Or as @Rufein said
double roundOff = (double) Math.round(a * 100) / 100;
this will do it for you as well.
double d = 2.34568;
DecimalFormat f = new DecimalFormat("##.00");
System.out.println(f.format(d));
As specified in javadoc, a BigDecimal is defined by an integer value and a scale.
The value of the number represented by the BigDecimal is therefore (unscaledValue × 10^(-scale)).
So BigDecimal("1761e+5") has scale -5 and BigDecimal(176100000) has scale 0.
The division of the two BigDecimal is done using the -5 and 0 scales respectively because the scales are not specified when dividing. The divide documentation explains why the results are different.
dividepublic BigDecimal divide(BigDecimal divisor)Returns a
BigDecimalwhose value is(this / divisor), and whose preferred scale is(this.scale() - divisor.scale()); if the exact quotient cannot be represented (because it has a non-terminating decimal expansion) anArithmeticExceptionis thrown.Parameters:
divisor- value by which this BigDecimal is to be divided.Returns:
this / divisorThrows:
ArithmeticException— if the exact quotient does not have a terminating decimal expansionSince:
1.5
If you specify a scale when dividing, e.g. dividendo.divide(BigDecimal.valueOf(1000), 0, RoundingMode.HALF_UP) you will get the same result.
The expressions new BigDecimal("176100000") and new BigDecimal("1761e+5") are not equal. BigDecimal keeps track of both value, and precision.
BigDecimal("176100000") has 9 digits of precision and is represented internally as the BigInteger("176100000"), multiplied by 1. BigDecimal("1761e+5") has 4 digits of precision and is represented internally as the BigInteger("1761"), multiplied by 100000.
When you a divide a BigDecimal by a value, the result respects the digits of precision, resulting in different outputs for seemingly equal values.
So far I can not come up with a solution, I tried the DecimalFormat class, but it doesn't work.
I have this so far:
double x = 2100.000000;DecimalFormat df = new DecimalFormat("0.00");String formatted = df.format(x);double y = Double.parseDouble(formatted);