|
11 | 11 | mpfr-lgamma |
12 | 12 | mpfr-jn |
13 | 13 | mpfr-yn |
14 | | - mpfr-sum |
15 | 14 | mpfr-set |
16 | 15 | mpfr-set-ebounds!) |
17 | 16 |
|
|
104 | 103 | (define (infinite-ordinal es sig) |
105 | 104 | (arithmetic-shift (sub1 (expt 2 es)) (sub1 sig))) |
106 | 105 |
|
107 | | -(define (ordinal->mpfr x es sig) |
108 | | - (define bound (invalid-ordinal es sig)) |
| 106 | +(define (ordinal->mpfr x es p) |
| 107 | + (define bound (invalid-ordinal es p)) |
109 | 108 | (unless (< (- bound) x bound) |
110 | 109 | (error 'ordinal->mpfr "ordinal out of bounds ~a" x)) |
111 | 110 | (let loop ([x x]) |
112 | 111 | (cond |
113 | 112 | [(zero? x) 0.bf] |
114 | 113 | [(negative? x) (bf- (loop (- x)))] |
115 | | - [(> x (infinite-ordinal es sig)) +nan.bf] |
116 | | - [(= x (infinite-ordinal es sig)) +inf.bf] |
| 114 | + [(> x (infinite-ordinal es p)) +nan.bf] |
| 115 | + [(= x (infinite-ordinal es p)) +inf.bf] |
117 | 116 | [else ; non-zero, real number |
118 | | - (define msize (sub1 sig)) |
119 | 117 | (define expmin (sub1 (mpfr-get-emin))) |
120 | | - (define ebits (arithmetic-shift x (- msize))) |
121 | | - (define mbits (bitwise-and x (sub1 (expt 2 msize)))) |
| 118 | + (define mask (sub1 (expt 2 (sub1 p)))) |
| 119 | + (define mbits (bitwise-and x mask)) |
| 120 | + (define ebits (arithmetic-shift x (- (sub1 p)))) |
122 | 121 | (cond |
123 | 122 | [(zero? ebits) ; subnormal |
124 | 123 | (bf mbits expmin)] |
125 | 124 | [else ; normal number |
126 | | - (define c (+ (expt 2 msize) mbits)) |
| 125 | + (define c (+ (expt 2 (sub1 p)) mbits)) |
127 | 126 | (define exp (+ (sub1 ebits) expmin)) |
128 | 127 | (bf c exp)])]))) |
129 | 128 |
|
130 | | -(define (mpfr->ordinal x es sig) |
| 129 | +(define (mpfr->ordinal x es p) |
131 | 130 | (let loop ([x x]) |
132 | 131 | (cond |
133 | 132 | [(bfzero? x) 0] |
134 | 133 | [(bfnegative? x) (- (loop (bf- x)))] |
135 | | - [(bfnan? x) (add1 (infinite-ordinal es sig))] |
136 | | - [(bfinfinite? x) (infinite-ordinal es sig)] |
| 134 | + [(bfnan? x) (add1 (infinite-ordinal es p))] |
| 135 | + [(bfinfinite? x) (infinite-ordinal es p)] |
137 | 136 | [else |
138 | | - (define-values (c exp) (bigfloat->sig+exp x)) |
139 | | - (define e (+ exp (bigfloat-precision x) -1)) |
| 137 | + ; format constants |
| 138 | + ; with subnormalization MPFR's emin is not what you think it is |
140 | 139 | (define expmin (sub1 (mpfr-get-emin))) |
141 | | - (define emin (+ expmin sig -1)) |
| 140 | + (define emin (+ expmin p -1)) |
| 141 | + ; extract fields |
| 142 | + ; per MPFR documentation, `mpfr_get_z_2exp(x)` extracts the integer |
| 143 | + ; using the (full) initialization precision of `x`. |
| 144 | + (define-values (c exp) (bigfloat->sig+exp x)) |
| 145 | + (define e (+ exp (sub1 p))) |
142 | 146 | (cond |
143 | | - [(< e emin) ; subnormal |
144 | | - (define shift (- exp expmin)) |
145 | | - (arithmetic-shift c shift)] |
146 | | - [else ; normal |
147 | | - (define ebits (add1 (- exp expmin))) |
148 | | - (define mbits (bitwise-and c (sub1 (expt 2 (sub1 sig))))) |
149 | | - (+ (arithmetic-shift ebits (sub1 sig)) mbits)])]))) |
| 147 | + [(< e emin) |
| 148 | + ; subnormal number |
| 149 | + ; since `x` is fully normalized `exp < expmin` |
| 150 | + (define shift (- expmin exp)) |
| 151 | + (arithmetic-shift c (- shift))] |
| 152 | + [else |
| 153 | + ; normal number |
| 154 | + (define mask (sub1 (expt 2 (sub1 p)))) |
| 155 | + (define mbits (bitwise-and mask c)) |
| 156 | + (define ebits (add1 (- e emin))) |
| 157 | + (+ (arithmetic-shift ebits (sub1 p)) mbits)])]))) |
0 commit comments