# HG changeset patch # User Paul (paul.d.anderson@comcast.net) # Date 1269406463 25200 # Node ID c991b9fde45cc095e6bb6be62b4d737c9311bbb9 # Parent b304232c476c6fb4790e1280d4c3b1758b3764d1 added rounding (partially implemented) diff -r b304232c476c -r c991b9fde45c src/decimal/bcd.d --- a/src/decimal/bcd.d Tue Mar 23 20:50:07 2010 -0700 +++ b/src/decimal/bcd.d Tue Mar 23 21:54:23 2010 -0700 @@ -1187,12 +1187,6 @@ } public Bcd truncate(const Bcd a, int n) { -/+ if (n <= 0) return ZERO.dup; - if (n >= a.numDigits) return a.dup; - Bcd b; - b.digits = a.digits[$-n..$].dup; - b.sign = a.sign; - return b;+/ Bcd dummy; return truncate(a, n, dummy); } @@ -1486,6 +1480,72 @@ writeln("passed"); } +/** + * Rounds the specified integer to the specified number of digits. + * The rounding mode governs the method of rounding. + */ +public Bcd round(Bcd a, int n, Rounding mode) { + Bcd r; + Bcd b = truncate(a, n, r); + return b; +} + +/** + * Rounds the (truncated) integer based on its remainder and the rounding + * mode. + */ +public Bcd round(Bcd a, Bcd r, Rounding mode) { + Bcd b = a.dup; + switch (mode) { + case Rounding.DOWN: + return b; + + case Rounding.HALF_UP: + if (r.firstDigit >= 5) b++; + return b; + + case Rounding.HALF_EVEN: +/+ BigInt test = 5 * pow10(numDigits(remainder,1)-1); + int result = remainder.opCmp(test); + if (result > 0) { + increment(number.ceff); + return; + } + if (result < 0) { + return; + } + // if last digit is odd... + if (lastDigit(number.ceff) & 1 == 1) { + increment(number.ceff); + }+/ + return b; + + case Rounding.CEILING: + if (!b.isSigned && !r.isZero) b++; + return b; + + case Rounding.FLOOR: + if (b.isSigned && !r.isZero) b++; + return b; + + // TODO: is this one right? what about 55... + case Rounding.HALF_DOWN: + if (r.firstDigit > 5) b++; + return b; + + case Rounding.UP: + if (!r.isZero) b++; + return b; + } + return b; +} + +unittest { + write("rounding......."); + writeln("passed"); +} + + //========================================== public void main() {