Handle known discrepancies between decimal.py and _decimal.so. These are either ULP differences in the power function or extremely minor issues.
| 385 | # ====================================================================== |
| 386 | |
| 387 | class SkipHandler: |
| 388 | """Handle known discrepancies between decimal.py and _decimal.so. |
| 389 | These are either ULP differences in the power function or |
| 390 | extremely minor issues.""" |
| 391 | |
| 392 | def __init__(self): |
| 393 | self.ulpdiff = 0 |
| 394 | self.powmod_zeros = 0 |
| 395 | self.maxctx = P.Context(Emax=10**18, Emin=-10**18) |
| 396 | |
| 397 | def default(self, t): |
| 398 | return False |
| 399 | __ge__ = __gt__ = __le__ = __lt__ = __ne__ = __eq__ = default |
| 400 | __reduce__ = __format__ = __repr__ = __str__ = default |
| 401 | |
| 402 | def harrison_ulp(self, dec): |
| 403 | """ftp://ftp.inria.fr/INRIA/publication/publi-pdf/RR/RR-5504.pdf""" |
| 404 | a = dec.next_plus() |
| 405 | b = dec.next_minus() |
| 406 | return abs(a - b) |
| 407 | |
| 408 | def standard_ulp(self, dec, prec): |
| 409 | return _dec_from_triple(0, '1', dec._exp+len(dec._int)-prec) |
| 410 | |
| 411 | def rounding_direction(self, x, mode): |
| 412 | """Determine the effective direction of the rounding when |
| 413 | the exact result x is rounded according to mode. |
| 414 | Return -1 for downwards, 0 for undirected, 1 for upwards, |
| 415 | 2 for ROUND_05UP.""" |
| 416 | cmp = 1 if x.compare_total(P.Decimal("+0")) >= 0 else -1 |
| 417 | |
| 418 | if mode in (P.ROUND_HALF_EVEN, P.ROUND_HALF_UP, P.ROUND_HALF_DOWN): |
| 419 | return 0 |
| 420 | elif mode == P.ROUND_CEILING: |
| 421 | return 1 |
| 422 | elif mode == P.ROUND_FLOOR: |
| 423 | return -1 |
| 424 | elif mode == P.ROUND_UP: |
| 425 | return cmp |
| 426 | elif mode == P.ROUND_DOWN: |
| 427 | return -cmp |
| 428 | elif mode == P.ROUND_05UP: |
| 429 | return 2 |
| 430 | else: |
| 431 | raise ValueError("Unexpected rounding mode: %s" % mode) |
| 432 | |
| 433 | def check_ulpdiff(self, exact, rounded): |
| 434 | # current precision |
| 435 | p = context.p.prec |
| 436 | |
| 437 | # Convert infinities to the largest representable number + 1. |
| 438 | x = exact |
| 439 | if exact.is_infinite(): |
| 440 | x = _dec_from_triple(exact._sign, '10', context.p.Emax) |
| 441 | y = rounded |
| 442 | if rounded.is_infinite(): |
| 443 | y = _dec_from_triple(rounded._sign, '10', context.p.Emax) |
| 444 |
no outgoing calls
no test coverage detected
searching dependent graphs…