Skip to content

Commit 332416d

Browse files
committed
libm: Add an optimization for trunc
Suggested-by: Juho Kahala <57393910+quaternic@users.noreply.github.com>
1 parent dd22b63 commit 332416d

File tree

1 file changed

+16
-14
lines changed

1 file changed

+16
-14
lines changed

libm/src/math/generic/trunc.rs

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,32 +10,34 @@ pub fn trunc<F: Float>(x: F) -> F {
1010

1111
#[inline]
1212
pub fn trunc_status<F: Float>(x: F) -> FpResult<F> {
13-
let mut xi: F::Int = x.to_bits();
13+
let xi: F::Int = x.to_bits();
1414
let e: i32 = x.exp_unbiased();
1515

1616
// The represented value has no fractional part, so no truncation is needed
1717
if e >= F::SIG_BITS as i32 {
1818
return FpResult::ok(x);
1919
}
2020

21-
let mask = if e < 0 {
22-
// If the exponent is negative, the result will be zero so we mask out everything
21+
let clear_mask = if e < 0 {
22+
// If the exponent is negative, the result will be zero so we clear everything
2323
// except the sign.
24-
F::SIGN_MASK
24+
!F::SIGN_MASK
2525
} else {
26-
// Otherwise, we mask out the last `e` bits of the significand.
27-
!(F::SIG_MASK >> e.unsigned())
26+
// Otherwise, we clear the last `e` bits of the significand.
27+
F::SIG_MASK >> e.unsigned()
2828
};
2929

30-
// If the to-be-masked-out portion is already zero, we have an exact result
31-
if (xi & !mask) == IntTy::<F>::ZERO {
32-
return FpResult::ok(x);
33-
}
30+
let cleared = xi & clear_mask;
31+
let status = if cleared == IntTy::<F>::ZERO {
32+
// If the to-be-zeroed portion is already zero, we have an exact result.
33+
Status::OK
34+
} else {
35+
// Otherwise the result is inexact and we will truncate, so indicate `FE_INEXACT`.
36+
Status::INEXACT
37+
};
3438

35-
// Otherwise the result is inexact and we will truncate. Raise `FE_INEXACT`, mask the
36-
// result, and return.
37-
xi &= mask;
38-
FpResult::new(F::from_bits(xi), Status::INEXACT)
39+
// Now zero the bits we need to truncate and return.
40+
FpResult::new(F::from_bits(xi ^ cleared), status)
3941
}
4042

4143
#[cfg(test)]

0 commit comments

Comments
 (0)