1
+ use super :: super :: support:: Hexf ;
1
2
use super :: super :: { CastFrom , CastInto , Float , IntTy , MinInt } ;
2
3
4
+ extern crate std;
5
+ use std:: dbg;
6
+
3
7
/// Scale the exponent.
4
8
///
5
9
/// From N3220:
@@ -40,76 +44,80 @@ where
40
44
// 2 ^ sig_total_bits, representation of what can be accounted for with subnormals
41
45
let f_exp_subnorm = F :: from_parts ( false , sig_total_bits + F :: EXP_BIAS , zero) ;
42
46
47
+ dbg ! ( ( Hexf ( f_exp_max) , Hexf ( f_exp_min) , Hexf ( f_exp_subnorm) ) ) ;
48
+
49
+ dbg ! ( Hexf ( x) , n) ;
50
+
51
+ // The goal is to multiply `x` by a scale factor that applies `n`. However, there are cases
52
+ // where `2^n` is not representable by `F` but the result should be, e.g. `x = 2^Emin` with
53
+ // `n = -EMin + 2`. To get around this, reduce the magnitude of the final scale operation by
54
+ // prescaling by the max/min power representable by `F`.
55
+
43
56
if n > exp_max {
57
+ // Worse case positive `n`: `x` is the minimum subnormal value, the result is `F::MAX`.
58
+ // This can be reached by three scaling multiplications (two here and one final).
59
+ debug_assert ! ( -exp_min + F :: SIG_BITS as i32 + exp_max <= exp_max * 3 ) ;
60
+
44
61
x *= f_exp_max;
45
62
n -= exp_max;
46
63
if n > exp_max {
47
64
x *= f_exp_max;
48
65
n -= exp_max;
49
-
50
- if F :: BITS < 32 && n > exp_max {
51
- x *= f_exp_max;
52
- n -= exp_max;
53
-
54
- if n > exp_max {
55
- x *= f_exp_max;
56
- n -= exp_max;
57
- if n > exp_max {
58
- x *= f_exp_max;
59
- n -= exp_max;
60
- if n > exp_max {
61
- x *= f_exp_max;
62
- n -= exp_max;
63
- if n > exp_max {
64
- n = exp_max;
65
- }
66
- }
67
- }
68
- }
69
- } else if n > exp_max {
66
+ if n > exp_max {
70
67
n = exp_max;
71
68
}
72
69
}
73
70
} else if n < exp_min {
74
71
let mul = f_exp_min * f_exp_subnorm;
75
72
let add = ( exp_max - 1 ) - sig_total_bits as i32 ;
73
+ dbg ! ( Hexf ( mul) , add) ;
76
74
77
75
x *= mul;
78
76
n += add;
77
+ dbg ! ( Hexf ( x) , n) ;
79
78
if n < exp_min {
80
79
x *= mul;
81
80
n += add;
81
+ dbg ! ( Hexf ( x) , n) ;
82
82
if F :: BITS < 32 {
83
83
if n < exp_min {
84
84
x *= mul;
85
85
n += add;
86
86
87
+ dbg ! ( Hexf ( x) , n) ;
87
88
if n < exp_min {
88
89
x *= mul;
89
90
n += add;
90
91
92
+ dbg ! ( Hexf ( x) , n) ;
91
93
if n < exp_min {
92
94
x *= mul;
93
95
n += add;
94
96
97
+ dbg ! ( Hexf ( x) , n) ;
95
98
if n < exp_min {
96
99
x *= mul;
97
100
n += add;
98
101
102
+ dbg ! ( Hexf ( x) , n) ;
99
103
if n < exp_min {
100
104
x *= mul;
101
105
n += add;
102
106
107
+ dbg ! ( Hexf ( x) , n) ;
103
108
if n < exp_min {
104
109
x *= mul;
105
110
n += add;
106
111
112
+ dbg ! ( Hexf ( x) , n) ;
107
113
if n < exp_min {
108
114
x *= mul;
109
115
n += add;
110
116
117
+ dbg ! ( Hexf ( x) , n) ;
111
118
if n < exp_min {
112
119
n = exp_min;
120
+ dbg ! ( Hexf ( x) , n) ;
113
121
}
114
122
}
115
123
}
@@ -120,11 +128,19 @@ where
120
128
}
121
129
} else if n < exp_min {
122
130
n = exp_min;
131
+ dbg ! ( Hexf ( x) , n) ;
123
132
}
124
133
}
125
134
}
126
135
127
- x * F :: from_parts ( false , ( F :: EXP_BIAS as i32 + n) as u32 , zero)
136
+ dbg ! ( Hexf ( x) , n) ;
137
+ let scale = F :: from_parts ( false , ( F :: EXP_BIAS as i32 + n) as u32 , zero) ;
138
+ let ret = x * scale;
139
+ dbg ! ( Hexf ( scale) , Hexf ( ret) ) ;
140
+ ret
141
+
142
+ // let ret = dbg!(x) * dbg!(F::from_parts(false, (F::EXP_BIAS as i32 + n) as u32, zero));
143
+ // dbg!(ret)
128
144
}
129
145
130
146
#[ cfg( test) ]
@@ -191,4 +207,28 @@ mod tests {
191
207
fn spec_test_f128 ( ) {
192
208
spec_test :: < f128 > ( ) ;
193
209
}
210
+
211
+ // #[test]
212
+ // fn foobar32() {
213
+ // let x = hf32!("0x1.fffffep+127");
214
+ // let n = -2147483639;
215
+ // scalbn(x, n);
216
+ // std::eprintln!();
217
+ // let x = hf32!("0x1.fffffep-126");
218
+ // let n = 2147483639;
219
+ // scalbn(x, n);
220
+ // panic!();
221
+ // }
222
+
223
+ // #[test]
224
+ // fn foobar16() {
225
+ // let x = hf16!("0x1.ffp+15");
226
+ // let n = -2147483639;
227
+ // scalbn(x, n);
228
+ // std::eprintln!();
229
+ // let x = hf16!("0x1.ffp-15");
230
+ // let n = 2147483639;
231
+ // scalbn(x, n);
232
+ // panic!();
233
+ // }
194
234
}
0 commit comments