|
105 | 105 | ival-== |
106 | 106 | ival-!= |
107 | 107 | ival-if |
| 108 | + ival-mobilize |
108 | 109 | ival-and |
109 | 110 | ival-or |
110 | 111 | ival-not |
|
661 | 662 | (ival (endpoint lo #f) (endpoint hi #f) err? err)) |
662 | 663 |
|
663 | 664 | (define (ival-fmin x y) |
664 | | - (ival (endpoint-min2 (ival-lo x) (ival-lo y) 'down) |
665 | | - (endpoint-min2 (ival-hi x) (ival-hi y) 'up) |
666 | | - (or (ival-err? x) (ival-err? y)) |
667 | | - (or (ival-err x) (ival-err y)))) |
| 665 | + (match-define (ival (endpoint xlo xlo!) (endpoint xhi xhi!) xerr? xerr) x) |
| 666 | + (match-define (ival (endpoint ylo ylo!) (endpoint yhi yhi!) yerr? yerr) y) |
| 667 | + (define lo (bf 0)) |
| 668 | + (define hi (bf 0)) |
| 669 | + (define lo-exact? (= 0 (mpfr-min! lo xlo ylo 'down))) |
| 670 | + (define hi-exact? (= 0 (mpfr-min! hi xhi yhi 'up))) |
| 671 | + ;; For lower endpoints (which can only move upward under refinement), |
| 672 | + ;; a fixed minimum is stable if one fixed endpoint is <= the other. |
| 673 | + (define lo-stable? |
| 674 | + (cond |
| 675 | + [(and xlo! ylo!) #t] |
| 676 | + [xlo! (bflte? xlo ylo)] |
| 677 | + [ylo! (bflte? ylo xlo)] |
| 678 | + [else #f])) |
| 679 | + (define lo! (and lo-exact? lo-stable?)) |
| 680 | + ;; For upper endpoints (which can only move downward), a fixed minimum is |
| 681 | + ;; only guaranteed when both endpoints are fixed. |
| 682 | + (define hi! (and hi-exact? xhi! yhi!)) |
| 683 | + (ival (endpoint lo lo!) (endpoint hi hi!) (or xerr? yerr?) (or xerr yerr))) |
668 | 684 |
|
669 | 685 | (define (ival-fmax x y) |
670 | | - (ival (endpoint-max2 (ival-lo x) (ival-lo y) 'down) |
671 | | - (endpoint-max2 (ival-hi x) (ival-hi y) 'up) |
672 | | - (or (ival-err? x) (ival-err? y)) |
673 | | - (or (ival-err x) (ival-err y)))) |
| 686 | + (match-define (ival (endpoint xlo xlo!) (endpoint xhi xhi!) xerr? xerr) x) |
| 687 | + (match-define (ival (endpoint ylo ylo!) (endpoint yhi yhi!) yerr? yerr) y) |
| 688 | + (define lo (bf 0)) |
| 689 | + (define hi (bf 0)) |
| 690 | + (define lo-exact? (= 0 (mpfr-max! lo xlo ylo 'down))) |
| 691 | + (define hi-exact? (= 0 (mpfr-max! hi xhi yhi 'up))) |
| 692 | + ;; For lower endpoints (which can only move upward), a fixed maximum is |
| 693 | + ;; only guaranteed when both endpoints are fixed. |
| 694 | + (define lo! (and lo-exact? xlo! ylo!)) |
| 695 | + ;; For upper endpoints (which can only move downward), a fixed maximum is |
| 696 | + ;; stable if one fixed endpoint is >= the other. |
| 697 | + (define hi-stable? |
| 698 | + (cond |
| 699 | + [(and xhi! yhi!) #t] |
| 700 | + [xhi! (bfgte? xhi yhi)] |
| 701 | + [yhi! (bfgte? yhi xhi)] |
| 702 | + [else #f])) |
| 703 | + (define hi! (and hi-exact? hi-stable?)) |
| 704 | + (ival (endpoint lo lo!) (endpoint hi hi!) (or xerr? yerr?) (or xerr yerr))) |
674 | 705 |
|
675 | 706 | (define (ival-copysign x y) |
676 | 707 | (match-define (ival xlo xhi xerr? xerr) (ival-fabs x)) |
677 | 708 | (define can-zero (or (bfzero? (ival-lo-val y)) (bfzero? (ival-hi-val y)))) |
678 | 709 | ;; 0 is both positive and negative because we don't handle signed zero well |
679 | 710 | (define can-neg (or (= (mpfr-sign (ival-lo-val y)) -1) can-zero)) |
680 | 711 | (define can-pos (or (= (mpfr-sign (ival-hi-val y)) 1) can-zero)) |
| 712 | + (define sign-immovable? (and can-neg can-pos (ival-lo-fixed? y) (ival-hi-fixed? y))) |
681 | 713 | (define err? (or (ival-err? y) xerr?)) |
682 | 714 | (define err (or (ival-err y) xerr)) |
683 | 715 | (match* (can-neg can-pos) |
684 | | - [(#t #t) (ival (rnd 'down epunary bfneg xhi) (rnd 'up epunary bfcopy xhi) err? err)] |
| 716 | + [(#t #t) |
| 717 | + (define out (ival (rnd 'down epunary bfneg xhi) (rnd 'up epunary bfcopy xhi) err? err)) |
| 718 | + (if sign-immovable? |
| 719 | + out |
| 720 | + (ival-mobilize out))] |
685 | 721 | [(#t #f) (ival (rnd 'down epunary bfneg xhi) (rnd 'up epunary bfneg xlo) err? err)] |
686 | 722 | [(#f #t) (ival xlo xhi err? err)] |
687 | 723 | [(#f #f) |
|
0 commit comments