1#![allow(unknown_lints)] use core::{fmt, mem, ops};
4
5use super::int_traits::{CastFrom, Int, MinInt};
6
7#[allow(dead_code)] pub trait Float:
11 Copy
12 + fmt::Debug
13 + PartialEq
14 + PartialOrd
15 + ops::AddAssign
16 + ops::MulAssign
17 + ops::Add<Output = Self>
18 + ops::Sub<Output = Self>
19 + ops::Mul<Output = Self>
20 + ops::Div<Output = Self>
21 + ops::Rem<Output = Self>
22 + ops::Neg<Output = Self>
23 + 'static
24{
25 type Int: Int<OtherSign = Self::SignedInt, Unsigned = Self::Int>;
27
28 type SignedInt: Int
30 + MinInt<OtherSign = Self::Int, Unsigned = Self::Int>
31 + ops::Neg<Output = Self::SignedInt>;
32
33 const ZERO: Self;
34 const NEG_ZERO: Self;
35 const ONE: Self;
36 const NEG_ONE: Self;
37 const INFINITY: Self;
38 const NEG_INFINITY: Self;
39 const NAN: Self;
40 const NEG_NAN: Self;
41 const MAX: Self;
42 const MIN: Self;
43 const EPSILON: Self;
44 const PI: Self;
45 const NEG_PI: Self;
46 const FRAC_PI_2: Self;
47
48 const MIN_POSITIVE_NORMAL: Self;
49
50 const BITS: u32;
52
53 const SIG_BITS: u32;
55
56 const EXP_BITS: u32 = Self::BITS - Self::SIG_BITS - 1;
58
59 const EXP_SAT: u32 = (1 << Self::EXP_BITS) - 1;
64
65 const EXP_BIAS: u32 = Self::EXP_SAT >> 1;
67
68 const EXP_MAX: i32 = Self::EXP_BIAS as i32;
70
71 const EXP_MIN: i32 = -(Self::EXP_MAX - 1);
73
74 const EXP_MIN_SUBNORM: i32 = Self::EXP_MIN - Self::SIG_BITS as i32;
76
77 const SIGN_MASK: Self::Int;
79
80 const SIG_MASK: Self::Int;
82
83 const EXP_MASK: Self::Int;
85
86 const IMPLICIT_BIT: Self::Int;
88
89 fn to_bits(self) -> Self::Int;
91
92 #[allow(dead_code)]
94 fn to_bits_signed(self) -> Self::SignedInt {
95 self.to_bits().signed()
96 }
97
98 #[allow(dead_code)]
100 fn biteq(self, rhs: Self) -> bool {
101 self.to_bits() == rhs.to_bits()
102 }
103
104 #[allow(dead_code)]
110 fn eq_repr(self, rhs: Self) -> bool {
111 if self.is_nan() && rhs.is_nan() {
112 true
113 } else {
114 self.biteq(rhs)
115 }
116 }
117
118 fn is_nan(self) -> bool;
120
121 fn is_infinite(self) -> bool;
123
124 fn is_sign_negative(self) -> bool;
126
127 fn is_sign_positive(self) -> bool {
129 !self.is_sign_negative()
130 }
131
132 #[allow(dead_code)]
134 fn is_subnormal(self) -> bool {
135 (self.to_bits() & Self::EXP_MASK) == Self::Int::ZERO
136 }
137
138 fn ex(self) -> u32 {
140 u32::cast_from(self.to_bits() >> Self::SIG_BITS) & Self::EXP_SAT
141 }
142
143 fn exp_unbiased(self) -> i32 {
145 self.ex().signed() - (Self::EXP_BIAS as i32)
146 }
147
148 #[allow(dead_code)]
150 fn frac(self) -> Self::Int {
151 self.to_bits() & Self::SIG_MASK
152 }
153
154 fn from_bits(a: Self::Int) -> Self;
156
157 fn from_parts(negative: bool, exponent: u32, significand: Self::Int) -> Self {
159 let sign = if negative {
160 Self::Int::ONE
161 } else {
162 Self::Int::ZERO
163 };
164 Self::from_bits(
165 (sign << (Self::BITS - 1))
166 | (Self::Int::cast_from(exponent & Self::EXP_SAT) << Self::SIG_BITS)
167 | (significand & Self::SIG_MASK),
168 )
169 }
170
171 #[allow(dead_code)]
172 fn abs(self) -> Self;
173
174 fn copysign(self, other: Self) -> Self;
176
177 fn fma(self, y: Self, z: Self) -> Self;
179
180 #[allow(dead_code)]
182 fn normalize(significand: Self::Int) -> (i32, Self::Int);
183
184 #[allow(dead_code)]
186 fn signum(self) -> Self {
187 if self.is_nan() {
188 self
189 } else {
190 Self::ONE.copysign(self)
191 }
192 }
193
194 fn canonicalize(self) -> Self {
197 self * Self::ONE
201 }
202}
203
204pub type IntTy<F> = <F as Float>::Int;
206
207macro_rules! float_impl {
208 (
209 $ty:ident,
210 $ity:ident,
211 $sity:ident,
212 $bits:expr,
213 $significand_bits:expr,
214 $from_bits:path,
215 $to_bits:path,
216 $fma_fn:ident,
217 $fma_intrinsic:ident
218 ) => {
219 impl Float for $ty {
220 type Int = $ity;
221 type SignedInt = $sity;
222
223 const ZERO: Self = 0.0;
224 const NEG_ZERO: Self = -0.0;
225 const ONE: Self = 1.0;
226 const NEG_ONE: Self = -1.0;
227 const INFINITY: Self = Self::INFINITY;
228 const NEG_INFINITY: Self = Self::NEG_INFINITY;
229 const NAN: Self = Self::NAN;
230 const NEG_NAN: Self = $from_bits($to_bits(Self::NAN) | Self::SIGN_MASK);
233 const MAX: Self = -Self::MIN;
234 const MIN: Self = $from_bits(Self::Int::MAX & !(1 << Self::SIG_BITS));
236 const EPSILON: Self = <$ty>::EPSILON;
237
238 const MIN_POSITIVE_NORMAL: Self = $from_bits(1 << Self::SIG_BITS);
240
241 const PI: Self = core::$ty::consts::PI;
242 const NEG_PI: Self = -Self::PI;
243 const FRAC_PI_2: Self = core::$ty::consts::FRAC_PI_2;
244
245 const BITS: u32 = $bits;
246 const SIG_BITS: u32 = $significand_bits;
247
248 const SIGN_MASK: Self::Int = 1 << (Self::BITS - 1);
249 const SIG_MASK: Self::Int = (1 << Self::SIG_BITS) - 1;
250 const EXP_MASK: Self::Int = !(Self::SIGN_MASK | Self::SIG_MASK);
251 const IMPLICIT_BIT: Self::Int = 1 << Self::SIG_BITS;
252
253 fn to_bits(self) -> Self::Int {
254 self.to_bits()
255 }
256 fn is_nan(self) -> bool {
257 self.is_nan()
258 }
259 fn is_infinite(self) -> bool {
260 self.is_infinite()
261 }
262 fn is_sign_negative(self) -> bool {
263 self.is_sign_negative()
264 }
265 fn from_bits(a: Self::Int) -> Self {
266 Self::from_bits(a)
267 }
268 fn abs(self) -> Self {
269 cfg_if! {
270 if #[cfg(intrinsics_enabled)] {
272 self.abs()
273 } else {
274 super::super::generic::fabs(self)
275 }
276 }
277 }
278 fn copysign(self, other: Self) -> Self {
279 cfg_if! {
280 if #[cfg(intrinsics_enabled)] {
282 self.copysign(other)
283 } else {
284 super::super::generic::copysign(self, other)
285 }
286 }
287 }
288 fn fma(self, y: Self, z: Self) -> Self {
289 cfg_if! {
290 if #[cfg(intrinsics_enabled)] {
292 #[allow(unused_unsafe)]
295 unsafe { core::intrinsics::$fma_intrinsic(self, y, z) }
296 } else {
297 super::super::$fma_fn(self, y, z)
298 }
299 }
300 }
301 fn normalize(significand: Self::Int) -> (i32, Self::Int) {
302 let shift = significand.leading_zeros().wrapping_sub(Self::EXP_BITS);
303 (
304 1i32.wrapping_sub(shift as i32),
305 significand << shift as Self::Int,
306 )
307 }
308 }
309 };
310}
311
312#[cfg(f16_enabled)]
313float_impl!(
314 f16,
315 u16,
316 i16,
317 16,
318 10,
319 f16::from_bits,
320 f16::to_bits,
321 fmaf16,
322 fmaf16
323);
324impl Float for f32 {
type Int = u32;
type SignedInt = i32;
const ZERO: Self = 0.0;
const NEG_ZERO: Self = -0.0;
const ONE: Self = 1.0;
const NEG_ONE: Self = -1.0;
const INFINITY: Self = Self::INFINITY;
const NEG_INFINITY: Self = Self::NEG_INFINITY;
const NAN: Self = Self::NAN;
const NEG_NAN: Self =
f32_from_bits(f32_to_bits(Self::NAN) | Self::SIGN_MASK);
const MAX: Self = -Self::MIN;
const MIN: Self = f32_from_bits(Self::Int::MAX & !(1 << Self::SIG_BITS));
const EPSILON: Self = <f32>::EPSILON;
const MIN_POSITIVE_NORMAL: Self = f32_from_bits(1 << Self::SIG_BITS);
const PI: Self = core::f32::consts::PI;
const NEG_PI: Self = -Self::PI;
const FRAC_PI_2: Self = core::f32::consts::FRAC_PI_2;
const BITS: u32 = 32;
const SIG_BITS: u32 = 23;
const SIGN_MASK: Self::Int = 1 << (Self::BITS - 1);
const SIG_MASK: Self::Int = (1 << Self::SIG_BITS) - 1;
const EXP_MASK: Self::Int = !(Self::SIGN_MASK | Self::SIG_MASK);
const IMPLICIT_BIT: Self::Int = 1 << Self::SIG_BITS;
fn to_bits(self) -> Self::Int { self.to_bits() }
fn is_nan(self) -> bool { self.is_nan() }
fn is_infinite(self) -> bool { self.is_infinite() }
fn is_sign_negative(self) -> bool { self.is_sign_negative() }
fn from_bits(a: Self::Int) -> Self { Self::from_bits(a) }
fn abs(self) -> Self { super::super::generic::fabs(self) }
fn copysign(self, other: Self) -> Self {
super::super::generic::copysign(self, other)
}
fn fma(self, y: Self, z: Self) -> Self { super::super::fmaf(self, y, z) }
fn normalize(significand: Self::Int) -> (i32, Self::Int) {
let shift = significand.leading_zeros().wrapping_sub(Self::EXP_BITS);
(1i32.wrapping_sub(shift as i32), significand << shift as Self::Int)
}
}float_impl!(
325 f32,
326 u32,
327 i32,
328 32,
329 23,
330 f32_from_bits,
331 f32_to_bits,
332 fmaf,
333 fmaf32
334);
335impl Float for f64 {
type Int = u64;
type SignedInt = i64;
const ZERO: Self = 0.0;
const NEG_ZERO: Self = -0.0;
const ONE: Self = 1.0;
const NEG_ONE: Self = -1.0;
const INFINITY: Self = Self::INFINITY;
const NEG_INFINITY: Self = Self::NEG_INFINITY;
const NAN: Self = Self::NAN;
const NEG_NAN: Self =
f64_from_bits(f64_to_bits(Self::NAN) | Self::SIGN_MASK);
const MAX: Self = -Self::MIN;
const MIN: Self = f64_from_bits(Self::Int::MAX & !(1 << Self::SIG_BITS));
const EPSILON: Self = <f64>::EPSILON;
const MIN_POSITIVE_NORMAL: Self = f64_from_bits(1 << Self::SIG_BITS);
const PI: Self = core::f64::consts::PI;
const NEG_PI: Self = -Self::PI;
const FRAC_PI_2: Self = core::f64::consts::FRAC_PI_2;
const BITS: u32 = 64;
const SIG_BITS: u32 = 52;
const SIGN_MASK: Self::Int = 1 << (Self::BITS - 1);
const SIG_MASK: Self::Int = (1 << Self::SIG_BITS) - 1;
const EXP_MASK: Self::Int = !(Self::SIGN_MASK | Self::SIG_MASK);
const IMPLICIT_BIT: Self::Int = 1 << Self::SIG_BITS;
fn to_bits(self) -> Self::Int { self.to_bits() }
fn is_nan(self) -> bool { self.is_nan() }
fn is_infinite(self) -> bool { self.is_infinite() }
fn is_sign_negative(self) -> bool { self.is_sign_negative() }
fn from_bits(a: Self::Int) -> Self { Self::from_bits(a) }
fn abs(self) -> Self { super::super::generic::fabs(self) }
fn copysign(self, other: Self) -> Self {
super::super::generic::copysign(self, other)
}
fn fma(self, y: Self, z: Self) -> Self { super::super::fma(self, y, z) }
fn normalize(significand: Self::Int) -> (i32, Self::Int) {
let shift = significand.leading_zeros().wrapping_sub(Self::EXP_BITS);
(1i32.wrapping_sub(shift as i32), significand << shift as Self::Int)
}
}float_impl!(
336 f64,
337 u64,
338 i64,
339 64,
340 52,
341 f64_from_bits,
342 f64_to_bits,
343 fma,
344 fmaf64
345);
346#[cfg(f128_enabled)]
347float_impl!(
348 f128,
349 u128,
350 i128,
351 128,
352 112,
353 f128::from_bits,
354 f128::to_bits,
355 fmaf128,
356 fmaf128
357);
358
359#[allow(unnecessary_transmutes)] pub const fn f32_from_bits(bits: u32) -> f32 {
364 unsafe { mem::transmute::<u32, f32>(bits) }
366}
367
368#[allow(dead_code)] #[allow(unnecessary_transmutes)] pub const fn f32_to_bits(x: f32) -> u32 {
372 unsafe { mem::transmute::<f32, u32>(x) }
374}
375
376#[allow(unnecessary_transmutes)] pub const fn f64_from_bits(bits: u64) -> f64 {
379 unsafe { mem::transmute::<u64, f64>(bits) }
381}
382
383#[allow(dead_code)] #[allow(unnecessary_transmutes)] pub const fn f64_to_bits(x: f64) -> u64 {
387 unsafe { mem::transmute::<f64, u64>(x) }
389}
390
391pub trait DFloat: Float {
393 type H: HFloat<D = Self>;
395
396 fn narrow(self) -> Self::H;
398}
399
400pub trait HFloat: Float {
402 type D: DFloat<H = Self>;
404
405 fn widen(self) -> Self::D;
407}
408
409macro_rules! impl_d_float {
410 ($($X:ident $D:ident),*) => {
411 $(
412 impl DFloat for $D {
413 type H = $X;
414
415 fn narrow(self) -> Self::H {
416 self as $X
417 }
418 }
419 )*
420 };
421}
422
423macro_rules! impl_h_float {
424 ($($H:ident $X:ident),*) => {
425 $(
426 impl HFloat for $H {
427 type D = $X;
428
429 fn widen(self) -> Self::D {
430 self as $X
431 }
432 }
433 )*
434 };
435}
436
437impl DFloat for f64 {
type H = f32;
fn narrow(self) -> Self::H { self as f32 }
}impl_d_float!(f32 f64);
438#[cfg(f16_enabled)]
439impl_d_float!(f16 f32);
440#[cfg(f128_enabled)]
441impl_d_float!(f64 f128);
442
443impl HFloat for f32 {
type D = f64;
fn widen(self) -> Self::D { self as f64 }
}impl_h_float!(f32 f64);
444#[cfg(f16_enabled)]
445impl_h_float!(f16 f32);
446#[cfg(f128_enabled)]
447impl_h_float!(f64 f128);
448
449#[cfg(test)]
450mod tests {
451 use super::*;
452
453 #[test]
454 #[cfg(f16_enabled)]
455 fn check_f16() {
456 assert_eq!(f16::EXP_SAT, 0b11111);
458 assert_eq!(f16::EXP_BIAS, 15);
459 assert_eq!(f16::EXP_MAX, 15);
460 assert_eq!(f16::EXP_MIN, -14);
461 assert_eq!(f16::EXP_MIN_SUBNORM, -24);
462
463 assert_eq!(f16::FRAC_PI_2.exp_unbiased(), 0);
465 assert_eq!((1.0f16 / 2.0).exp_unbiased(), -1);
466 assert_eq!(f16::MAX.exp_unbiased(), 15);
467 assert_eq!(f16::MIN.exp_unbiased(), 15);
468 assert_eq!(f16::MIN_POSITIVE.exp_unbiased(), -14);
469 assert_eq!(f16::ZERO.exp_unbiased(), -15);
472 assert_eq!(f16::from_bits(0x1).exp_unbiased(), -15);
473 assert_eq!(f16::MIN_POSITIVE, f16::MIN_POSITIVE_NORMAL);
474
475 assert_biteq!(f16::from_parts(true, f16::EXP_BIAS, 0), -1.0f16);
477 assert_biteq!(f16::from_parts(false, 0, 1), f16::from_bits(0x1));
478 }
479
480 #[test]
481 fn check_f32() {
482 assert_eq!(f32::EXP_SAT, 0b11111111);
484 assert_eq!(f32::EXP_BIAS, 127);
485 assert_eq!(f32::EXP_MAX, 127);
486 assert_eq!(f32::EXP_MIN, -126);
487 assert_eq!(f32::EXP_MIN_SUBNORM, -149);
488
489 assert_eq!(f32::FRAC_PI_2.exp_unbiased(), 0);
491 assert_eq!((1.0f32 / 2.0).exp_unbiased(), -1);
492 assert_eq!(f32::MAX.exp_unbiased(), 127);
493 assert_eq!(f32::MIN.exp_unbiased(), 127);
494 assert_eq!(f32::MIN_POSITIVE.exp_unbiased(), -126);
495 assert_eq!(f32::ZERO.exp_unbiased(), -127);
498 assert_eq!(f32::from_bits(0x1).exp_unbiased(), -127);
499 assert_eq!(f32::MIN_POSITIVE, f32::MIN_POSITIVE_NORMAL);
500
501 assert_biteq!(f32::from_parts(true, f32::EXP_BIAS, 0), -1.0f32);
503 assert_biteq!(
504 f32::from_parts(false, 10 + f32::EXP_BIAS, 0),
505 hf32!("0x1p10")
506 );
507 assert_biteq!(f32::from_parts(false, 0, 1), f32::from_bits(0x1));
508 }
509
510 #[test]
511 fn check_f64() {
512 assert_eq!(f64::EXP_SAT, 0b11111111111);
514 assert_eq!(f64::EXP_BIAS, 1023);
515 assert_eq!(f64::EXP_MAX, 1023);
516 assert_eq!(f64::EXP_MIN, -1022);
517 assert_eq!(f64::EXP_MIN_SUBNORM, -1074);
518
519 assert_eq!(f64::FRAC_PI_2.exp_unbiased(), 0);
521 assert_eq!((1.0f64 / 2.0).exp_unbiased(), -1);
522 assert_eq!(f64::MAX.exp_unbiased(), 1023);
523 assert_eq!(f64::MIN.exp_unbiased(), 1023);
524 assert_eq!(f64::MIN_POSITIVE.exp_unbiased(), -1022);
525 assert_eq!(f64::ZERO.exp_unbiased(), -1023);
528 assert_eq!(f64::from_bits(0x1).exp_unbiased(), -1023);
529 assert_eq!(f64::MIN_POSITIVE, f64::MIN_POSITIVE_NORMAL);
530
531 assert_biteq!(f64::from_parts(true, f64::EXP_BIAS, 0), -1.0f64);
533 assert_biteq!(
534 f64::from_parts(false, 10 + f64::EXP_BIAS, 0),
535 hf64!("0x1p10")
536 );
537 assert_biteq!(f64::from_parts(false, 0, 1), f64::from_bits(0x1));
538 }
539
540 #[test]
541 #[cfg(f128_enabled)]
542 fn check_f128() {
543 assert_eq!(f128::EXP_SAT, 0b111111111111111);
545 assert_eq!(f128::EXP_BIAS, 16383);
546 assert_eq!(f128::EXP_MAX, 16383);
547 assert_eq!(f128::EXP_MIN, -16382);
548 assert_eq!(f128::EXP_MIN_SUBNORM, -16494);
549
550 assert_eq!(f128::FRAC_PI_2.exp_unbiased(), 0);
552 assert_eq!((1.0f128 / 2.0).exp_unbiased(), -1);
553 assert_eq!(f128::MAX.exp_unbiased(), 16383);
554 assert_eq!(f128::MIN.exp_unbiased(), 16383);
555 assert_eq!(f128::MIN_POSITIVE.exp_unbiased(), -16382);
556 assert_eq!(f128::ZERO.exp_unbiased(), -16383);
559 assert_eq!(f128::from_bits(0x1).exp_unbiased(), -16383);
560 assert_eq!(f128::MIN_POSITIVE, f128::MIN_POSITIVE_NORMAL);
561
562 assert_biteq!(f128::from_parts(true, f128::EXP_BIAS, 0), -1.0f128);
564 assert_biteq!(f128::from_parts(false, 0, 1), f128::from_bits(0x1));
565 }
566}