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

Commit c3df336

Browse files
committed
scalbn wip
1 parent c9a691c commit c3df336

File tree

1 file changed

+55
-0
lines changed

1 file changed

+55
-0
lines changed

src/math/generic/scalbn.rs

+55
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,49 @@
11
use 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.
319
pub fn scalbn<F: Float>(mut x: F, mut n: i32) -> F
420
where
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

Comments
 (0)