comparison src/decimal/bcd.d @ 8:c991b9fde45c

added rounding (partially implemented)
author Paul (paul.d.anderson@comcast.net)
date Tue, 23 Mar 2010 21:54:23 -0700
parents b304232c476c
children 48d564218e05
comparison
equal deleted inserted replaced
7:b304232c476c 8:c991b9fde45c
1185 assert(c == 7); 1185 assert(c == 7);
1186 writeln("passed"); 1186 writeln("passed");
1187 } 1187 }
1188 1188
1189 public Bcd truncate(const Bcd a, int n) { 1189 public Bcd truncate(const Bcd a, int n) {
1190 /+ if (n <= 0) return ZERO.dup;
1191 if (n >= a.numDigits) return a.dup;
1192 Bcd b;
1193 b.digits = a.digits[$-n..$].dup;
1194 b.sign = a.sign;
1195 return b;+/
1196 Bcd dummy; 1190 Bcd dummy;
1197 return truncate(a, n, dummy); 1191 return truncate(a, n, dummy);
1198 } 1192 }
1199 1193
1200 unittest { 1194 unittest {
1484 b = rotate(a, -4); 1478 b = rotate(a, -4);
1485 assert(b.toString == "1234"); 1479 assert(b.toString == "1234");
1486 writeln("passed"); 1480 writeln("passed");
1487 } 1481 }
1488 1482
1483 /**
1484 * Rounds the specified integer to the specified number of digits.
1485 * The rounding mode governs the method of rounding.
1486 */
1487 public Bcd round(Bcd a, int n, Rounding mode) {
1488 Bcd r;
1489 Bcd b = truncate(a, n, r);
1490 return b;
1491 }
1492
1493 /**
1494 * Rounds the (truncated) integer based on its remainder and the rounding
1495 * mode.
1496 */
1497 public Bcd round(Bcd a, Bcd r, Rounding mode) {
1498 Bcd b = a.dup;
1499 switch (mode) {
1500 case Rounding.DOWN:
1501 return b;
1502
1503 case Rounding.HALF_UP:
1504 if (r.firstDigit >= 5) b++;
1505 return b;
1506
1507 case Rounding.HALF_EVEN:
1508 /+ BigInt test = 5 * pow10(numDigits(remainder,1)-1);
1509 int result = remainder.opCmp(test);
1510 if (result > 0) {
1511 increment(number.ceff);
1512 return;
1513 }
1514 if (result < 0) {
1515 return;
1516 }
1517 // if last digit is odd...
1518 if (lastDigit(number.ceff) & 1 == 1) {
1519 increment(number.ceff);
1520 }+/
1521 return b;
1522
1523 case Rounding.CEILING:
1524 if (!b.isSigned && !r.isZero) b++;
1525 return b;
1526
1527 case Rounding.FLOOR:
1528 if (b.isSigned && !r.isZero) b++;
1529 return b;
1530
1531 // TODO: is this one right? what about 55...
1532 case Rounding.HALF_DOWN:
1533 if (r.firstDigit > 5) b++;
1534 return b;
1535
1536 case Rounding.UP:
1537 if (!r.isZero) b++;
1538 return b;
1539 }
1540 return b;
1541 }
1542
1543 unittest {
1544 write("rounding.......");
1545 writeln("passed");
1546 }
1547
1548
1489 //========================================== 1549 //==========================================
1490 1550
1491 public void main() { 1551 public void main() {
1492 writeln(); 1552 writeln();
1493 writeln("If you got this far all the unit tests were successful."); 1553 writeln("If you got this far all the unit tests were successful.");