1+ use super :: super :: support:: Hexf ;
12use super :: super :: { CastFrom , CastInto , Float , IntTy , MinInt } ;
23
4+ extern crate std;
5+ use std:: dbg;
6+
37/// Scale the exponent.
48///
59/// From N3220:
@@ -40,76 +44,80 @@ where
4044 // 2 ^ sig_total_bits, representation of what can be accounted for with subnormals
4145 let f_exp_subnorm = F :: from_parts ( false , sig_total_bits + F :: EXP_BIAS , zero) ;
4246
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+
4356 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+
4461 x *= f_exp_max;
4562 n -= exp_max;
4663 if n > exp_max {
4764 x *= f_exp_max;
4865 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 {
7067 n = exp_max;
7168 }
7269 }
7370 } else if n < exp_min {
7471 let mul = f_exp_min * f_exp_subnorm;
7572 let add = ( exp_max - 1 ) - sig_total_bits as i32 ;
73+ dbg ! ( Hexf ( mul) , add) ;
7674
7775 x *= mul;
7876 n += add;
77+ dbg ! ( Hexf ( x) , n) ;
7978 if n < exp_min {
8079 x *= mul;
8180 n += add;
81+ dbg ! ( Hexf ( x) , n) ;
8282 if F :: BITS < 32 {
8383 if n < exp_min {
8484 x *= mul;
8585 n += add;
8686
87+ dbg ! ( Hexf ( x) , n) ;
8788 if n < exp_min {
8889 x *= mul;
8990 n += add;
9091
92+ dbg ! ( Hexf ( x) , n) ;
9193 if n < exp_min {
9294 x *= mul;
9395 n += add;
9496
97+ dbg ! ( Hexf ( x) , n) ;
9598 if n < exp_min {
9699 x *= mul;
97100 n += add;
98101
102+ dbg ! ( Hexf ( x) , n) ;
99103 if n < exp_min {
100104 x *= mul;
101105 n += add;
102106
107+ dbg ! ( Hexf ( x) , n) ;
103108 if n < exp_min {
104109 x *= mul;
105110 n += add;
106111
112+ dbg ! ( Hexf ( x) , n) ;
107113 if n < exp_min {
108114 x *= mul;
109115 n += add;
110116
117+ dbg ! ( Hexf ( x) , n) ;
111118 if n < exp_min {
112119 n = exp_min;
120+ dbg ! ( Hexf ( x) , n) ;
113121 }
114122 }
115123 }
@@ -120,11 +128,19 @@ where
120128 }
121129 } else if n < exp_min {
122130 n = exp_min;
131+ dbg ! ( Hexf ( x) , n) ;
123132 }
124133 }
125134 }
126135
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)
128144}
129145
130146#[ cfg( test) ]
@@ -191,4 +207,28 @@ mod tests {
191207 fn spec_test_f128 ( ) {
192208 spec_test :: < f128 > ( ) ;
193209 }
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+ // }
194234}
0 commit comments