#[cfg(feature = "f16")]
use super::f016::{ceil_f32_f16, floor_f32_f16};
#[cfg(feature = "f16")]
use crate::float::{F016, F032, N5};
use crate::float::{float_ext_int, float_ext_int_l};
#[cfg(feature = "f16")]
fn f032f016_ceil(x: F032) -> F016 {
N5::new(ceil_f32_f16(x.into_inner()))
}
#[cfg(feature = "f16")]
fn f032f016_inner(y: F016) -> F032 {
N5::new(y.into_inner() as f32)
}
#[cfg(feature = "f16")]
fn f032f016_floor(x: F032) -> F016 {
N5::new(floor_f32_f16(x.into_inner()))
}
#[cfg(feature = "f16")]
#[cfg_attr(docsrs, doc(cfg(feature = "f16")))]
crate::conn_k! {
pub F032F016 : F032 => F016 {
ceil: f032f016_ceil,
inner: f032f016_inner,
floor: f032f016_floor,
}
}
float_ext_int! (
pub F032U008, f32, u8
);
float_ext_int! (
pub F032U016, f32, u16
);
float_ext_int_l!(
pub F032U032, f32, u32
);
float_ext_int_l!(
pub F032U064, f32, u64
);
float_ext_int! (
pub F032I008, f32, i8
);
float_ext_int! (
pub F032I016, f32, i16
);
float_ext_int_l!(
pub F032I032, f32, i32
);
float_ext_int_l!(
pub F032I064, f32, i64
);
#[cfg(test)]
mod tests {
use super::*;
use crate::extended::Extended;
use crate::float::N5;
use crate::prop::arb::{
arb_extended_i8, arb_extended_i16, arb_extended_i32, arb_extended_i64, arb_extended_u8,
arb_extended_u16, arb_extended_u32, arb_extended_u64, extended_float_f32,
};
#[test]
fn nan_ceil_pos_inf() {
assert_eq!(F032U008.view_l().ceil(N5::new(f32::NAN)), Extended::PosInf);
assert_eq!(F032I008.view_l().ceil(N5::new(f32::NAN)), Extended::PosInf);
assert_eq!(F032U064.ceil(N5::new(f32::NAN)), Extended::PosInf);
}
#[test]
fn nan_floor_neg_inf() {
assert_eq!(F032U008.view_r().floor(N5::new(f32::NAN)), Extended::NegInf);
assert_eq!(F032I016.view_r().floor(N5::new(f32::NAN)), Extended::NegInf);
}
#[test]
fn pos_inf_saturates_via_high_branch() {
assert_eq!(
F032U008.view_l().ceil(N5::new(f32::INFINITY)),
Extended::PosInf
);
assert_eq!(
F032I008.view_r().floor(N5::new(f32::INFINITY)),
Extended::PosInf
);
}
#[test]
fn neg_inf_saturates_via_low_branch() {
assert_eq!(
F032U008.view_l().ceil(N5::new(f32::NEG_INFINITY)),
Extended::NegInf
);
assert_eq!(
F032I008.view_l().ceil(N5::new(f32::NEG_INFINITY)),
Extended::NegInf
);
assert_eq!(
F032U008.view_r().floor(N5::new(f32::NEG_INFINITY)),
Extended::NegInf
);
assert_eq!(
F032I008.view_r().floor(N5::new(f32::NEG_INFINITY)),
Extended::NegInf
);
}
#[test]
fn infinities_pass_through() {
assert_eq!(
F032U008.view_l().ceil(N5::new(f32::NEG_INFINITY)),
Extended::NegInf
);
assert_eq!(
F032U008.view_r().floor(N5::new(f32::NEG_INFINITY)),
Extended::NegInf
);
assert_eq!(
F032U008.view_l().ceil(N5::new(f32::INFINITY)),
Extended::PosInf
);
assert_eq!(
F032U008.view_r().floor(N5::new(f32::INFINITY)),
Extended::PosInf
);
assert_eq!(F032I064.ceil(N5::new(f32::NEG_INFINITY)), Extended::NegInf);
assert_eq!(F032I064.ceil(N5::new(f32::INFINITY)), Extended::PosInf);
}
#[test]
fn saturate_high_unsigned() {
assert_eq!(F032U008.view_l().ceil(N5::new(300.0_f32)), Extended::PosInf);
assert_eq!(
F032U008.view_r().floor(N5::new(300.0_f32)),
Extended::Finite(u8::MAX)
);
}
#[test]
fn saturate_low_signed() {
assert_eq!(
F032I008.view_l().ceil(N5::new(-200.0_f32)),
Extended::Finite(i8::MIN)
);
assert_eq!(
F032I008.view_r().floor(N5::new(-200.0_f32)),
Extended::NegInf
);
}
#[test]
fn saturate_low_unsigned() {
assert_eq!(
F032U008.view_l().ceil(N5::new(-1.0_f32)),
Extended::Finite(0)
);
assert_eq!(F032U008.view_r().floor(N5::new(-1.0_f32)), Extended::NegInf);
}
#[test]
fn exact_integer_round_trip() {
assert_eq!(
F032U008.view_l().ceil(N5::new(42.0_f32)),
Extended::Finite(42)
);
assert_eq!(
F032U008.view_r().floor(N5::new(42.0_f32)),
Extended::Finite(42)
);
assert_eq!(
F032I016.view_l().ceil(N5::new(-1234.0_f32)),
Extended::Finite(-1234)
);
}
#[test]
fn fraction_brackets_integer() {
assert_eq!(
F032I008.view_l().ceil(N5::new(2.5_f32)),
Extended::Finite(3)
);
assert_eq!(
F032I008.view_r().floor(N5::new(2.5_f32)),
Extended::Finite(2)
);
}
#[test]
fn inner_round_trip_finite() {
assert_eq!(
F032U008.view_l().upper(Extended::Finite(42_u8)),
N5::new(42.0_f32)
);
assert_eq!(
F032U008.view_l().upper(Extended::NegInf),
N5::new(f32::NEG_INFINITY)
);
assert_eq!(
F032U008.view_l().upper(Extended::PosInf),
N5::new(f32::INFINITY)
);
}
#[test]
fn f032u032_at_plateau_to_posinf() {
let plateau = N5::new(2.0_f32.powi(32));
assert_eq!(F032U032.ceil(plateau), Extended::PosInf);
}
#[test]
fn f032i032_at_plateau_to_posinf() {
let plateau = N5::new(2.0_f32.powi(31));
assert_eq!(F032I032.ceil(plateau), Extended::PosInf);
}
#[test]
fn f032u064_at_plateau_to_posinf() {
let plateau = N5::new(2.0_f32.powi(64));
assert_eq!(F032U064.ceil(plateau), Extended::PosInf);
}
#[test]
fn f032i064_at_plateau_to_posinf() {
let plateau = N5::new(2.0_f32.powi(63));
assert_eq!(F032I064.ceil(plateau), Extended::PosInf);
}
crate::law_battery! { mod laws_u008, conn: F032U008, fine: extended_float_f32(), coarse: arb_extended_u8(), cases: 1024, }
crate::law_battery! { mod laws_u016, conn: F032U016, fine: extended_float_f32(), coarse: arb_extended_u16(), cases: 1024, }
crate::law_battery! { mod laws_u032, conn: F032U032, fine: extended_float_f32(), coarse: arb_extended_u32(), subset: l_only, cases: 1024, }
crate::law_battery! { mod laws_u064, conn: F032U064, fine: extended_float_f32(), coarse: arb_extended_u64(), subset: l_only, cases: 1024, }
crate::law_battery! { mod laws_i008, conn: F032I008, fine: extended_float_f32(), coarse: arb_extended_i8(), cases: 1024, }
crate::law_battery! { mod laws_i016, conn: F032I016, fine: extended_float_f32(), coarse: arb_extended_i16(), cases: 1024, }
crate::law_battery! { mod laws_i032, conn: F032I032, fine: extended_float_f32(), coarse: arb_extended_i32(), subset: l_only, cases: 1024, }
crate::law_battery! { mod laws_i064, conn: F032I064, fine: extended_float_f32(), coarse: arb_extended_i64(), subset: l_only, cases: 1024, }
}