Skip to content

Commit 2557bd2

Browse files
committed
Implements direct rounding for pow and pow2
1 parent fc97a4b commit 2557bd2

File tree

3 files changed

+44
-34
lines changed

3 files changed

+44
-34
lines changed

mpfr.rkt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,9 @@
142142

143143
(define mpfr-set-prec! set-mpfr-prec!)
144144

145+
(define (mpfr-pow2! out a rnd)
146+
(mpfr-mul! out a a rnd))
147+
145148
(define (bfremainder x mod)
146149
(define out (bf 0))
147150
(mpfr-remainder! out x mod (bf-rounding-mode))
@@ -346,5 +349,6 @@
346349
mpfr-log!
347350
mpfr-const-pi!
348351
mpfr-atan2!
352+
mpfr-pow2!
349353
mpfr-set-prec!
350354
mpfr-set!)

ops/core.rkt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,12 @@
3232
ival-union
3333
ival-split
3434
(rename-out [monotonic monotonic->ival] [comonotonic comonotonic->ival])
35+
define*
36+
immutable
37+
monotonic-mpfr!
38+
comonotonic-mpfr!
39+
monotonic-mpfr
40+
comonotonic-mpfr
3541
ival-illegal
3642
ival-pi
3743
ival-e

ops/pow.rkt

Lines changed: 34 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,15 @@
1313
[(and (< (mpfr-exp (ival-hi-val x)) 1) (not (bfinfinite? (ival-hi-val x)))) -1]
1414
[else 0]))
1515

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
2121
(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)))
2525
(and b! (bfzero? b))
2626
(and b! (bfinfinite? b) (not (= a-class 0))))))
2727

@@ -39,24 +39,25 @@
3939
(define y-class (classify-ival y))
4040

4141
(define (mk-pow a b c d)
42+
(define out (new-ival (bf-precision)))
4243
(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))
5152
(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))
6061

6162
(define-values (real-lo! real-hi!)
6263
(cond
@@ -69,17 +70,16 @@
6970
;; Can't use >=, even though exp2-overflow-threshold is a
7071
;; power of 2, because mpfr-exp is offset by 1 from the real
7172
;; 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+
7278
(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)))
7780

7881
(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)))
8383

8484
(define real-lo! (or lo! must-underflow (and (bfzero? lo) a! b!)))
8585
(define real-hi! (or hi! must-underflow must-overflow (and (bfinfinite? hi) c! d!)))
@@ -152,8 +152,8 @@
152152
(let ([pospow (ival-pow-pos (ival-exact-fabs x) y)])
153153
(ival-then (ival-assert ival-maybe) (ival-union (ival-neg pospow) pospow)))))
154154

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!))
157157

158158
(define (ival-pow x y)
159159
(cond

0 commit comments

Comments
 (0)