Mercurial > projects > decimal
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."); |