max(min(x, hi), lo)
}
-/// Returns the nearest integer to a given `f32`.
-///
-/// Respects IEEE-754 tiesToEven
-#[inline(always)]
-fn round_ties_to_even(x: f32) -> f32 {
- #[cfg(target_feature = "sse4.1")]
- unsafe {
- use std::arch::x86_64::{
- _mm_load_ss, _mm_round_ss, _MM_FROUND_NO_EXC, _MM_FROUND_TO_NEAREST_INT,
- };
- const ROUNDING: i32 = _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC;
- let x = _mm_load_ss(&x);
- let x = _mm_round_ss::<ROUNDING>(x, x);
- std::arch::x86_64::_mm_cvtss_f32(x)
- }
-
- // Incorrect if the rounding mode is changed.
- #[cfg(not(target_feature = "sse4.1"))]
- x.round()
-}
-
pub fn quantize_centered(x: f32, n: u32) -> u32 {
(x * ((n - 1) as f32) + 0.5) as u32
}
//
// Sollya code for generating these polynomials is in `doc/sincostan.sollya`
-use crate::round_ties_to_even;
-
// constants for sin(pi x), cos(pi x) for x on [-1/4,1/4]
const F32_SIN_PI_7_K: [f32; 3] = unsafe {
std::mem::transmute::<[u32; 3], _>([
let a = if a.abs() < 16777216.0 { a } else { a * 0.0 };
// Range reduction.
- let r = round_ties_to_even(a + a);
+ let r = (a + a).round_ties_even();
// SAFETY: The clamp above avoids the possibility of overflow here.
let i = unsafe { r.to_int_unchecked::<i32>() } as u32;
//
// Sollya code for generating these polynomials is in `doc/sincostan.sollya`
-use crate::round_ties_to_even;
-
const F32_TAN_PI_15_K: [f32; 7] = unsafe {
std::mem::transmute::<[u32; 7], _>([
0x41255def, // 0x1.4abbdep3
const T: [f32; 7] = F32_TAN_PI_15_K;
// Range reduction.
- let r = round_ties_to_even(a + a);
+ let r = (a + a).round_ties_even();
// SAFETY: The clamp above avoids the possibility of overflow here.
let i = unsafe { r.to_int_unchecked::<i32>() } as u32;