Over the weekend, I ran into a situation where I needed more fine-grained rounding than ColdFusion supports. Rather than rounding to the closest whole number, I wanted to be able to round to a specific decimal place. For instance, given the number 2.345, I didn’t want the number 2; I wanted the number 2.35. Fortunately, Java picks up where ColdFusion leaves off. The following UDF lets you specify the number of places to round to:

// mode can be "up", "down", or "even". Even is the default.function decimalRound(numberToRound, numberOfPlaces, mode){var bd = createObject("java", "java.math.BigDecimal");bd.init(arguments.numberToRound);if (structCount(arguments) eq 1){mode = "even";}if (mode is "up"){bd = bd.setScale(arguments.numberOfPlaces,bd.ROUND_HALF_UP);}else if (mode is "down"){bd = bd.setScale(arguments.numberOfPlaces,bd.ROUND_HALF_DOWN);}else{bd = bd.setScale(arguments.numberOfPlaces,bd.ROUND_HALF_EVEN);}return bd.toString();}

The mode is an interesting argument. Its meaning is clear for “up” and “down”, but “even” is a little more involved. What “even” means is that if the last digit in your number (the number to the left of the discarded portion of the original number) is even, round down, and if it’s odd, round up. In other words, half the time, act as through the mode were “up” and the other half, act as though the mode were “down”. This is the best way to eliminate cumulative round errors over a series of calculations, and worked perfectly for me.