Java BigDecimal: Round to the nearest whole value
Solution 1
You can use setScale()
to reduce the number of fractional digits to zero. Assuming value
holds the value to be rounded:
BigDecimal scaled = value.setScale(0, RoundingMode.HALF_UP);
System.out.println(value + " -> " + scaled);
Using round()
is a bit more involved as it requires you to specify the number of digits to be retained. In your examples this would be 3, but this is not valid for all values:
BigDecimal rounded = value.round(new MathContext(3, RoundingMode.HALF_UP));
System.out.println(value + " -> " + rounded);
(Note that BigDecimal
objects are immutable; both setScale
and round
will return a new object.)
Solution 2
If i go by Grodriguez's answer
System.out.println("" + value);
value = value.setScale(0, BigDecimal.ROUND_HALF_UP);
System.out.println("" + value);
This is the output
100.23 -> 100
100.77 -> 101
Which isn't quite what i want, so i ended up doing this..
System.out.println("" + value);
value = value.setScale(0, BigDecimal.ROUND_HALF_UP);
value = value.setScale(2, BigDecimal.ROUND_HALF_UP);
System.out.println("" + value);
This is what i get
100.23 -> 100.00
100.77 -> 101.00
This solves my problem for now .. : ) Thank you all.
Solution 3
Here's an awfully complicated solution, but it works:
public static BigDecimal roundBigDecimal(final BigDecimal input){
return input.round(
new MathContext(
input.toBigInteger().toString().length(),
RoundingMode.HALF_UP
)
);
}
Test Code:
List<BigDecimal> bigDecimals =
Arrays.asList(new BigDecimal("100.12"),
new BigDecimal("100.44"),
new BigDecimal("100.50"),
new BigDecimal("100.75"));
for(final BigDecimal bd : bigDecimals){
System.out.println(roundBigDecimal(bd).toPlainString());
}
Output:
100
100
101
101
Solution 4
Simply look at:
http://download.oracle.com/javase/6/docs/api/java/math/BigDecimal.html#ROUND_HALF_UP
and:
setScale(int precision, int roundingMode)
Or if using Java 6, then
http://download.oracle.com/javase/6/docs/api/java/math/RoundingMode.html#HALF_UP
http://download.oracle.com/javase/6/docs/api/java/math/MathContext.html
and either:
setScale(int precision, RoundingMode mode);
round(MathContext mc);
Related videos on Youtube
n a
Updated on March 07, 2020Comments
-
n a about 4 years
I need the following results
100.12 -> 100.00 100.44 -> 100.00 100.50 -> 101.00 100.75 -> 101.00
.round()
or.setScale()
? How do I go about this? -
Boris Pavlović over 13 yearsIt's not working: 100.12 : 100.12, 100.44 : 100.44, 100.50 : 100.5, 100.75 : 100.75
-
Daniel Fath over 13 yearsNo, setting scale returns a new decimal that isn't same as the first. For example:
BigDecimal bd1 = new BigDecimal(100.12); BigDecimal bd2 = bd1.setScale(0, RoundingMode.HALF_UP); System.out.println(bd1.equals(bd2));
prints false -
Grodriguez over 13 yearsThis does nothing. From the documentation of
round
: "If the precision setting is 0 then no rounding takes place." -
Grodriguez over 13 years@Daniel: That was already implied in the code snippet I posted in my answer. I've now made it explicit.
-
joel.neely about 8 yearsI am curious about the statement that the first result "isn't quite what I want...". If you are actually concerned about output formatting, you can use
DecimalFormat
(as innew DecimalFormat("###.00")
) to manage the conversion of aBigDecimal
back to string. It gives"101.00"
as the result for both values that the snippets from @Grodriquez and you created. -
kosmoplan about 7 yearsThe second time you are rounding here is unnecessary as you know you have an integer already, so I would use BigDecimal.ROUND_UNNECESSARY instead, a bit more clear in my opinion.
-
trilogy over 5 years
RoundingMode
what is that? It'sBigDecimal
-
Grodriguez over 5 years
-
Addison almost 5 yearsNot to endorse this solution or anything, but the
input.toBigInteger().toString().length()
part would be much more efficient by using a logarithm, some thing likeround_up(log(input)) + (1 if input is a power of ten, else 0)
-
MarkHu over 2 yearsBigDecimal seems like a steaming heap.