machina_softfloat/ops/
misc.rs1use crate::env::FloatEnv;
6use crate::parts::{round_pack, unpack, FloatClass};
7use crate::types::{
8 BFloat16, BitOps, Float128, Float16, Float32, Float64, FloatFormat,
9 FloatX80,
10};
11
12pub fn abs<F: FloatFormat>(a: F) -> F {
14 let bits = a.to_bits().to_u128();
15 let frac_total = if F::HAS_EXPLICIT_INT {
16 F::FRAC_BITS + 1
17 } else {
18 F::FRAC_BITS
19 };
20 let sign_pos = frac_total + F::EXP_BITS;
21 let mask = !(1u128 << sign_pos);
22 let result = bits & mask;
23 F::from_bits(<F::Bits as BitOps>::from_u128(result))
24}
25
26pub fn neg<F: FloatFormat>(a: F) -> F {
28 let bits = a.to_bits().to_u128();
29 let frac_total = if F::HAS_EXPLICIT_INT {
30 F::FRAC_BITS + 1
31 } else {
32 F::FRAC_BITS
33 };
34 let sign_pos = frac_total + F::EXP_BITS;
35 let result = bits ^ (1u128 << sign_pos);
36 F::from_bits(<F::Bits as BitOps>::from_u128(result))
37}
38
39pub fn scalbn<F: FloatFormat>(a: F, n: i32, env: &mut FloatEnv) -> F {
42 let mut parts = unpack::<F>(a);
43
44 match parts.cls {
45 FloatClass::Normal => {
46 parts.exp += n;
47 round_pack::<F>(&mut parts, env)
48 }
49 FloatClass::QNaN | FloatClass::SNaN => {
50 let mut r = crate::parts::nan_propagate_one(&parts, env);
51 round_pack::<F>(&mut r, env)
52 }
53 _ => {
54 round_pack::<F>(&mut parts, env)
56 }
57 }
58}
59
60pub fn classify<F: FloatFormat>(a: F) -> FloatClass {
62 let parts = unpack::<F>(a);
63 parts.cls
64}
65
66pub fn is_signaling_nan<F: FloatFormat>(a: F) -> bool {
68 let parts = unpack::<F>(a);
69 parts.cls == FloatClass::SNaN
70}
71
72pub fn is_quiet_nan<F: FloatFormat>(a: F) -> bool {
74 let parts = unpack::<F>(a);
75 parts.cls == FloatClass::QNaN
76}
77
78pub fn is_subnormal<F: FloatFormat>(a: F) -> bool {
82 let bits = a.to_bits().to_u128();
83 let frac_total = if F::HAS_EXPLICIT_INT {
84 F::FRAC_BITS + 1
85 } else {
86 F::FRAC_BITS
87 };
88 let exp_mask = (1u128 << F::EXP_BITS) - 1;
89 let raw_exp = (bits >> frac_total) & exp_mask;
90 let frac_mask = (1u128 << frac_total) - 1;
91 let raw_frac = bits & frac_mask;
92
93 raw_exp == 0 && raw_frac != 0
94}
95
96macro_rules! impl_misc {
101 ($ty:ty) => {
102 impl $ty {
103 pub fn abs(self) -> Self {
104 abs::<Self>(self)
105 }
106 #[allow(clippy::should_implement_trait)]
107 pub fn neg(self) -> Self {
108 neg::<Self>(self)
109 }
110 pub fn scalbn(self, n: i32, env: &mut FloatEnv) -> Self {
111 scalbn::<Self>(self, n, env)
112 }
113 pub fn classify(self) -> FloatClass {
114 classify::<Self>(self)
115 }
116 }
117 };
118}
119
120impl_misc!(Float16);
121impl_misc!(BFloat16);
122impl_misc!(Float32);
123impl_misc!(Float64);
124impl_misc!(Float128);
125impl_misc!(FloatX80);