Skip to content
This repository was archived by the owner on Apr 28, 2025. It is now read-only.

Commit 7064fb8

Browse files
committed
comments
1 parent d26ec87 commit 7064fb8

File tree

1 file changed

+62
-22
lines changed

1 file changed

+62
-22
lines changed

src/math/generic/scalbn.rs

Lines changed: 62 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1+
use super::super::support::Hexf;
12
use 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

Comments
 (0)