How can I round to a specific multiple in Java? In excel there is the mround function which allows for easy rounding to a specified multiple like so:
mRound(variable,multiple)
e.g. This is how the Java function should work for given 'Number' and 'Factor'. To get more test data, just add below 'Number' and 'Factor' columns in MS Excel and in the next column use excel's built in MROUND function as =MROUND(Number, Factor)
I know how it can be done with double, but I need a solution with BigDecimal as I am working with financial data.
Solution with double -
double mRound(double value, double factor) {
return Math.round(value / factor) * factor;
}
This is how excel MROUND function works - The MROUND Excel function rounds the number to the nearest multiple of the provided number. You must be thinking about how Excel knows whether to round up or round down. It depends on the result of the division.
For example 16 / 3 = 5.33333, here decimal value is less than 0.5 so result of nearest multiple value of number 3 is 5, so 3 * 5 = 15. Here, Excel rounds down the value if the decimal value is less than 0.5.
Similarly, look at this equation 20 / 3 = 6.66667. In this equation, the decimal value is greater than 0.5, so Excel rounds up the result to 7, so 3 * 7 = 21.
For more details on how MROUND works, refer - https://www.wallstreetmojo.com/mround-in-excel/

The
BigDecimalclass offers all needed methods to do the same asMath.round(value / factor) * factor;- rounding is a bit tricky, sinceBigDecimal#roundis usingMathContextwhich requires a precision: the total number of digits, not the number of digits of the fractional part. ButBigDecimal#setScaleis a replacement forMath#round.Assuming that both
valuesandfactorare alreadyBigDecimal, we would write your method as:I believe the
divde()andmultiply()methods do not need more explanation, for details refer to the javadoc ofBigDecimal.The
setScale()methods is used to round the number. As documented: "the scale is the number of digits to the right of the decimal point."We used:
scale: 0since we want no decimal digits;roundingMode: HALF_UPsince we want0.5or greater rounded upagain, see documentation for the different modes.
To remove the trailing zeros from the result, use the
stripTrailingZeros()method after multiplying:Please be aware that using
new BigDecimal(double)can cause problems sincedoubleis not an exact representation - usenew BigDecimal(String)instead!For example,
new BigDecimal(1.2)results in1.1999999999999999555910790149937383830547332763671875.Testing
Result
Note the result for
523.785 0.01does not match the given input image - I wonder if that is a bug in Excel (is it usingdouble?) :-/