| /* SPDX-License-Identifier: MIT | |
| * origin: musl src/math/trunc.c */ | |
| use crate::support::{Float, FpResult, Int, IntTy, MinInt, Status}; | |
| #[inline] | |
| pub fn trunc_status<F: Float>(x: F) -> FpResult<F> { | |
| let xi: F::Int = x.to_bits(); | |
| let e: i32 = x.exp_unbiased(); | |
| // The represented value has no fractional part, so no truncation is needed | |
| if e >= F::SIG_BITS as i32 { | |
| return FpResult::ok(x); | |
| } | |
| let clear_mask = if e < 0 { | |
| // If the exponent is negative, the result will be zero so we clear everything | |
| // except the sign. | |
| !F::SIGN_MASK | |
| } else { | |
| // Otherwise, we keep `e` fractional bits and clear the rest. | |
| F::SIG_MASK >> e.unsigned() | |
| }; | |
| let cleared = xi & clear_mask; | |
| let status = if cleared == IntTy::<F>::ZERO { | |
| // If the to-be-zeroed portion is already zero, we have an exact result. | |
| Status::OK | |
| } else { | |
| // Otherwise the result is inexact and we will truncate, so indicate `FE_INEXACT`. | |
| Status::INEXACT | |
| }; | |
| // Now zero the bits we need to truncate and return. | |
| FpResult::new(F::from_bits(xi ^ cleared), status) | |
| } |