Since people have such trouble with rounding to multiple of an integer number, whether rounding up/down/nearest, here are very simple methods for doing so:
public static int roundDown(int value, int multiplier) {
return value / multiplier * multiplier;
}
public static int roundHalfUp(int value, int multiplier) {
return (value + multiplier / 2) / multiplier * multiplier;
}
public static int roundUp(int value, int multiplier) {
return (value + multiplier - 1) / multiplier * multiplier;
}
Test
Value Down Half Up
0 0 0 0
1 0 0 4
2 0 4 4
3 0 4 4
4 4 4 4
Value Down Half Up
0 0 0 0
1 0 0 5
2 0 0 5
3 0 5 5
4 0 5 5
5 5 5 5
Negative Numbers
They don't work right for negative numbers. "Round down" usually means "towards zero", unlike Math.floor()
which rounds towards negative infinity.
Here are versions that can handle negative values. These are consistent with the RoundingMode
options of similar names used by BigDecimal
.
public static int roundDown(int value, int multiplier) {
if (multiplier <= 0) throw new IllegalArgumentException();
return value / multiplier * multiplier;
}
public static int roundHalfUp(int value, int multiplier) {
if (multiplier <= 0) throw new IllegalArgumentException();
return (value + (value < 0 ? multiplier / -2 : multiplier / 2)) / multiplier * multiplier;
}
public static int roundUp(int value, int multiplier) {
if (multiplier <= 0) throw new IllegalArgumentException();
return (value + (value < 0 ? 1 - multiplier : multiplier - 1)) / multiplier * multiplier;
}
Test
Value Down Half Up
-4 -4 -4 -4
-3 0 -4 -4
-2 0 -4 -4
-1 0 0 -4
0 0 0 0
1 0 0 4
2 0 4 4
3 0 4 4
4 4 4 4
Value Down Half Up
-5 -5 -5 -5
-4 0 -5 -5
-3 0 -5 -5
-2 0 0 -5
-1 0 0 -5
0 0 0 0
1 0 0 5
2 0 0 5
3 0 5 5
4 0 5 5
5 5 5 5