11use super :: super :: { CastFrom , CastInto , Float , IntTy , MinInt } ;
22
3+ /// Scale the exponent.
4+ ///
5+ /// From N3220:
6+ ///
7+ /// > The scalbn and scalbln functions compute `x * b^n`, where `b = FLT_RADIX` if the return type
8+ /// > of the function is a standard floating type, or `b = 10` if the return type of the function
9+ /// > is a decimal floating type. A range error occurs for some finite x, depending on n.
10+ /// >
11+ /// > [...]
12+ /// >
13+ /// > * `scalbn(±0, n)` returns `±0`.
14+ /// > * `scalbn(x, 0)` returns `x`.
15+ /// > * `scalbn(±∞, n)` returns `±∞`.
16+ /// >
17+ /// > If the calculation does not overflow or underflow, the returned value is exact and
18+ /// > independent of the current rounding direction mode.
319pub fn scalbn < F : Float > ( mut x : F , mut n : i32 ) -> F
420where
521 u32 : CastInto < F :: Int > ,
622 F :: Int : CastFrom < i32 > ,
723 F :: Int : CastFrom < u32 > ,
824{
25+ if n == 0 || x == F :: ZERO || x. is_nan ( ) || x. is_infinite ( ) {
26+ return x;
27+ }
28+
929 // Bits including the implicit bit
1030 let sig_total_bits = F :: SIG_BITS + 1 ;
1131
1232 // Maximum and minimum values when biased
1333 let exp_max: i32 = F :: EXP_BIAS as i32 ;
1434 let exp_min = -( exp_max - 1 ) ;
35+ let exp_min_with_subnorm = -( ( F :: EXP_BIAS + F :: SIG_BITS + 1 ) as i32 ) ;
36+
37+ // let x_exp = x.exp();
38+ // let x_sig = x.frac();
39+
40+ if n > exp_max {
41+ return F :: INFINITY * x. signum ( ) ;
42+ }
43+
44+ if n < exp_min_with_subnorm {
45+ return F :: ZERO * x. signum ( ) ;
46+ }
1547
1648 // 2 ^ Emax, where Emax is the maximum biased exponent value (1023 for f64)
1749 let f_exp_max = F :: from_bits ( F :: Int :: cast_from ( F :: EXP_BIAS << 1 ) << F :: SIG_BITS ) ;
@@ -20,14 +52,20 @@ where
2052 // 2 ^ sig_total_bits, representation of what can be accounted for with subnormals
2153 let f_exp_subnorm = F :: from_bits ( ( F :: EXP_BIAS + sig_total_bits) . cast ( ) << F :: SIG_BITS ) ;
2254
55+ // std::println!("{exp_max} {exp_min} {n}");
56+ // std::dbg!(x, exp_max, exp_min, n);
57+
2358 if n > exp_max {
2459 x *= f_exp_max;
2560 n -= exp_max;
61+ // std::dbg!(11, x, n);
2662 if n > exp_max {
2763 x *= f_exp_max;
2864 n -= exp_max;
65+ // std::dbg!(12, x, n);
2966 if n > exp_max {
3067 n = exp_max;
68+ // std::dbg!(13, x, n);
3169 }
3270 }
3371 } else if n < exp_min {
@@ -36,14 +74,31 @@ where
3674
3775 x *= mul;
3876 n += add;
77+ // std::dbg!(21, x, n);
3978 if n < exp_min {
4079 x *= mul;
4180 n += add;
81+ // std::dbg!(22, x, n);
4282 if n < exp_min {
4383 n = exp_min;
84+ // std::dbg!(23, x, n);
4485 }
4586 }
4687 }
4788
4889 x * F :: from_bits ( F :: Int :: cast_from ( F :: EXP_BIAS as i32 + n) << F :: SIG_BITS )
4990}
91+
92+ // DELETE
93+
94+ extern crate std;
95+
96+ #[ test]
97+ fn testme ( ) {
98+ assert_eq ! ( scalbn:: <f16>( f16:: from_bits( 0x6ecb ) , -1336428830 ) , f16:: ZERO ) ;
99+ }
100+
101+ #[ test]
102+ fn testme2 ( ) {
103+ // assert_eq!(scalbn(-f64::INFINITY, -2147033648), f64::ZERO);
104+ }
0 commit comments