Remainder nearest to 0- abs(remainder-near) <= other/2
(self, other, context=None)
| 1452 | return other.__mod__(self, context=context) |
| 1453 | |
| 1454 | def remainder_near(self, other, context=None): |
| 1455 | """ |
| 1456 | Remainder nearest to 0- abs(remainder-near) <= other/2 |
| 1457 | """ |
| 1458 | if context is None: |
| 1459 | context = getcontext() |
| 1460 | |
| 1461 | other = _convert_other(other, raiseit=True) |
| 1462 | |
| 1463 | ans = self._check_nans(other, context) |
| 1464 | if ans: |
| 1465 | return ans |
| 1466 | |
| 1467 | # self == +/-infinity -> InvalidOperation |
| 1468 | if self._isinfinity(): |
| 1469 | return context._raise_error(InvalidOperation, |
| 1470 | 'remainder_near(infinity, x)') |
| 1471 | |
| 1472 | # other == 0 -> either InvalidOperation or DivisionUndefined |
| 1473 | if not other: |
| 1474 | if self: |
| 1475 | return context._raise_error(InvalidOperation, |
| 1476 | 'remainder_near(x, 0)') |
| 1477 | else: |
| 1478 | return context._raise_error(DivisionUndefined, |
| 1479 | 'remainder_near(0, 0)') |
| 1480 | |
| 1481 | # other = +/-infinity -> remainder = self |
| 1482 | if other._isinfinity(): |
| 1483 | ans = Decimal(self) |
| 1484 | return ans._fix(context) |
| 1485 | |
| 1486 | # self = 0 -> remainder = self, with ideal exponent |
| 1487 | ideal_exponent = min(self._exp, other._exp) |
| 1488 | if not self: |
| 1489 | ans = _dec_from_triple(self._sign, '0', ideal_exponent) |
| 1490 | return ans._fix(context) |
| 1491 | |
| 1492 | # catch most cases of large or small quotient |
| 1493 | expdiff = self.adjusted() - other.adjusted() |
| 1494 | if expdiff >= context.prec + 1: |
| 1495 | # expdiff >= prec+1 => abs(self/other) > 10**prec |
| 1496 | return context._raise_error(DivisionImpossible) |
| 1497 | if expdiff <= -2: |
| 1498 | # expdiff <= -2 => abs(self/other) < 0.1 |
| 1499 | ans = self._rescale(ideal_exponent, context.rounding) |
| 1500 | return ans._fix(context) |
| 1501 | |
| 1502 | # adjust both arguments to have the same exponent, then divide |
| 1503 | op1 = _WorkRep(self) |
| 1504 | op2 = _WorkRep(other) |
| 1505 | if op1.exp >= op2.exp: |
| 1506 | op1.int *= 10**(op1.exp - op2.exp) |
| 1507 | else: |
| 1508 | op2.int *= 10**(op2.exp - op1.exp) |
| 1509 | q, r = divmod(op1.int, op2.int) |
| 1510 | # remainder is r*10**ideal_exponent; other is +/-op2.int * |
| 1511 | # 10**ideal_exponent. Apply correction to ensure that |