|
13 | 13 | [(and (< (mpfr-exp (ival-hi-val x)) 1) (not (bfinfinite? (ival-hi-val x)))) -1] |
14 | 14 | [else 0])) |
15 | 15 |
|
16 | | -(define (eppow a a! b b! a-class b-class) |
17 | | - (when (bfzero? a) |
18 | | - (set! a 0.bf)) ; Handle (-0)^(-1) |
19 | | - (define-values (val exact?) (bf-return-exact? bfexpt (list a b))) |
20 | | - (values val |
| 16 | +(define (eppow! out a a! b b! a-class b-class rnd) |
| 17 | + (define base (if (bfzero? a) 0.bf a)) ; Handle (-0)^(-1) |
| 18 | + (mpfr-set-prec! out (bf-precision)) |
| 19 | + (define exact? (= 0 (mpfr-pow! out base b rnd))) |
| 20 | + (values out |
21 | 21 | (or (and a! b! exact?) |
22 | | - (and a! (bf=? a 1.bf)) |
23 | | - (and a! (bfzero? a) (not (= b-class 0))) |
24 | | - (and a! (bfinfinite? a) (not (= b-class 0))) |
| 22 | + (and a! (bf=? base 1.bf)) |
| 23 | + (and a! (bfzero? base) (not (= b-class 0))) |
| 24 | + (and a! (bfinfinite? base) (not (= b-class 0))) |
25 | 25 | (and b! (bfzero? b)) |
26 | 26 | (and b! (bfinfinite? b) (not (= a-class 0)))))) |
27 | 27 |
|
|
39 | 39 | (define y-class (classify-ival y)) |
40 | 40 |
|
41 | 41 | (define (mk-pow a b c d) |
| 42 | + (define out (new-ival (bf-precision))) |
42 | 43 | (define-values (lo lo!) |
43 | | - (rnd 'down |
44 | | - eppow |
45 | | - (endpoint-val a) |
46 | | - (endpoint-immovable? a) |
47 | | - (endpoint-val b) |
48 | | - (endpoint-immovable? b) |
49 | | - x-class |
50 | | - y-class)) |
| 44 | + (eppow! (ival-lo-val out) |
| 45 | + (endpoint-val a) |
| 46 | + (endpoint-immovable? a) |
| 47 | + (endpoint-val b) |
| 48 | + (endpoint-immovable? b) |
| 49 | + x-class |
| 50 | + y-class |
| 51 | + 'down)) |
51 | 52 | (define-values (hi hi!) |
52 | | - (rnd 'up |
53 | | - eppow |
54 | | - (endpoint-val c) |
55 | | - (endpoint-immovable? c) |
56 | | - (endpoint-val d) |
57 | | - (endpoint-immovable? d) |
58 | | - x-class |
59 | | - y-class)) |
| 53 | + (eppow! (ival-hi-val out) |
| 54 | + (endpoint-val c) |
| 55 | + (endpoint-immovable? c) |
| 56 | + (endpoint-val d) |
| 57 | + (endpoint-immovable? d) |
| 58 | + x-class |
| 59 | + y-class |
| 60 | + 'up)) |
60 | 61 |
|
61 | 62 | (define-values (real-lo! real-hi!) |
62 | 63 | (cond |
|
69 | 70 | ;; Can't use >=, even though exp2-overflow-threshold is a |
70 | 71 | ;; power of 2, because mpfr-exp is offset by 1 from the real |
71 | 72 | ;; exponent, which matters when we add them. |
| 73 | + (define log2-base (bf 0)) |
| 74 | + (define (log2-sum-exceeds-threshold? exponent-value base-value) |
| 75 | + (mpfr-log2! log2-base base-value 'zero) |
| 76 | + (> (+ (mpfr-exp exponent-value) (mpfr-exp log2-base)) (mpfr-exp exp2-overflow-threshold))) |
| 77 | + |
72 | 78 | (define must-overflow |
73 | | - (and (bfinfinite? hi) |
74 | | - (= (* x-class y-class) 1) |
75 | | - (> (+ (mpfr-exp bval) (mpfr-exp (rnd 'zero bflog2 aval))) |
76 | | - (mpfr-exp exp2-overflow-threshold)))) |
| 79 | + (and (bfinfinite? hi) (= (* x-class y-class) 1) (log2-sum-exceeds-threshold? bval aval))) |
77 | 80 |
|
78 | 81 | (define must-underflow |
79 | | - (and (bfzero? lo) |
80 | | - (= (* x-class y-class) -1) |
81 | | - (> (+ (mpfr-exp dval) (mpfr-exp (rnd 'zero bflog2 cval))) |
82 | | - (mpfr-exp exp2-overflow-threshold)))) |
| 82 | + (and (bfzero? lo) (= (* x-class y-class) -1) (log2-sum-exceeds-threshold? dval cval))) |
83 | 83 |
|
84 | 84 | (define real-lo! (or lo! must-underflow (and (bfzero? lo) a! b!))) |
85 | 85 | (define real-hi! (or hi! must-underflow must-overflow (and (bfinfinite? hi) c! d!))) |
|
152 | 152 | (let ([pospow (ival-pow-pos (ival-exact-fabs x) y)]) |
153 | 153 | (ival-then (ival-assert ival-maybe) (ival-union (ival-neg pospow) pospow))))) |
154 | 154 |
|
155 | | -(define (ival-pow2 x) |
156 | | - ((monotonic->ival (lambda (x) (bfmul x x))) (ival-pre-fabs x))) |
| 155 | +(define* ival-pow2! (lambda (out x) ((monotonic-mpfr! mpfr-pow2!) out (ival-pre-fabs x)))) |
| 156 | +(define* ival-pow2 (immutable ival-pow2!)) |
157 | 157 |
|
158 | 158 | (define (ival-pow x y) |
159 | 159 | (cond |
|
0 commit comments