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.

Isn’t the easiest solution to the original problem of rounding x to 2 decimal places to do round(x*100)/100. You could easily write a cf udf to do this for n decimal places:function roundTo(x,n) {return round(x*(10^n))/(10^n)}

But then you don’t get the flexibility of rounding up, down or even. Once you build that in ColdFusion, it will have been much simpler just to delegate to Java.Christian

This is what we’ve written and use ://this function will return the given value fixed to parameter “decimals” formatedfunction tofixed(value, decimals) {var fixed=round(value*(10^decimals))/(10^decimals);var dekadika=Len(ListLast(fixed, ‘.’));if (fixed eq int(fixed))return fixed & ‘.’ & RepeatString(‘0’, decimals);elsereturn fixed & RepeatString(‘0’, decimals-dekadika);}

Hi Christian,Just wanted to warn you about the spam messages above from Erasmus and Melchior.