Skip to content

Commit 3560e43

Browse files
authored
Merge pull request #145 from herbie-fp/fix-fmin-fmax-movability
Fix fmin/fmax movability flags
2 parents 5c3ed59 + ffd873a commit 3560e43

File tree

2 files changed

+45
-9
lines changed

2 files changed

+45
-9
lines changed

ops/core.rkt

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@
105105
ival-==
106106
ival-!=
107107
ival-if
108+
ival-mobilize
108109
ival-and
109110
ival-or
110111
ival-not
@@ -661,16 +662,46 @@
661662
(ival (endpoint lo #f) (endpoint hi #f) err? err))
662663

663664
(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)))
668684

669685
(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)))
674705

675706
(define (ival-copysign x y)
676707
(match-define (ival xlo xhi xerr? xerr) (ival-fabs x))

ops/pow.rkt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,4 +161,9 @@
161161
[(or (= (mpfr-sign (ival-lo-val x)) 1) (bfzero? (ival-lo-val x))) (ival-pow-pos x y)]
162162
[else
163163
(define-values (neg pos) (split-ival x 0.bf))
164-
(ival-union (ival-pow-neg neg y) (ival-pow-pos pos y))]))
164+
(define out (ival-union (ival-pow-neg neg y) (ival-pow-pos pos y)))
165+
;; If x straddles 0 with movable endpoints, a refinement can drop one
166+
;; branch entirely, so branch-derived endpoint fixedness is not stable.
167+
(if (and (ival-lo-fixed? x) (ival-hi-fixed? x))
168+
out
169+
(ival-mobilize out))]))

0 commit comments

Comments
 (0)