add ilogb
[vector-math.git] / src / ieee754.rs
1 use crate::{
2 f16::F16,
3 scalar::Scalar,
4 traits::{Float, Make},
5 };
6
7 mod sealed {
8 use crate::f16::F16;
9
10 pub trait Sealed {}
11 impl Sealed for F16 {}
12 impl Sealed for f32 {}
13 impl Sealed for f64 {}
14 }
15
16 pub trait FloatEncoding:
17 sealed::Sealed + Copy + 'static + Send + Sync + Float<u32> + Make<Context = Scalar>
18 {
19 const EXPONENT_BIAS_UNSIGNED: Self::BitsType;
20 const EXPONENT_BIAS_SIGNED: Self::SignedBitsType;
21 const SIGN_FIELD_WIDTH: u32;
22 const EXPONENT_FIELD_WIDTH: u32;
23 const MANTISSA_FIELD_WIDTH: u32;
24 const SIGN_FIELD_SHIFT: u32;
25 const EXPONENT_FIELD_SHIFT: u32;
26 const MANTISSA_FIELD_SHIFT: u32;
27 const SIGN_FIELD_MASK: Self::BitsType;
28 const EXPONENT_FIELD_MASK: Self::BitsType;
29 const MANTISSA_FIELD_MASK: Self::BitsType;
30 const IMPLICIT_MANTISSA_BIT: Self::BitsType;
31 const ZERO_SUBNORMAL_EXPONENT: Self::BitsType;
32 const NAN_INFINITY_EXPONENT: Self::BitsType;
33 const INFINITY_BITS: Self::BitsType;
34 const NAN_BITS: Self::BitsType;
35 }
36
37 macro_rules! impl_float_encoding {
38 (
39 impl FloatEncoding for $float:ident {
40 const EXPONENT_FIELD_WIDTH: u32 = $exponent_field_width:literal;
41 const MANTISSA_FIELD_WIDTH: u32 = $mantissa_field_width:literal;
42 }
43 ) => {
44 impl FloatEncoding for $float {
45 const EXPONENT_BIAS_UNSIGNED: Self::BitsType =
46 (1 << (Self::EXPONENT_FIELD_WIDTH - 1)) - 1;
47 const EXPONENT_BIAS_SIGNED: Self::SignedBitsType = Self::EXPONENT_BIAS_UNSIGNED as _;
48 const SIGN_FIELD_WIDTH: u32 = 1;
49 const EXPONENT_FIELD_WIDTH: u32 = $exponent_field_width;
50 const MANTISSA_FIELD_WIDTH: u32 = $mantissa_field_width;
51 const SIGN_FIELD_SHIFT: u32 = Self::EXPONENT_FIELD_SHIFT + Self::EXPONENT_FIELD_WIDTH;
52 const EXPONENT_FIELD_SHIFT: u32 = Self::MANTISSA_FIELD_WIDTH;
53 const MANTISSA_FIELD_SHIFT: u32 = 0;
54 const SIGN_FIELD_MASK: Self::BitsType = 1 << Self::SIGN_FIELD_SHIFT;
55 const EXPONENT_FIELD_MASK: Self::BitsType =
56 ((1 << Self::EXPONENT_FIELD_WIDTH) - 1) << Self::EXPONENT_FIELD_SHIFT;
57 const MANTISSA_FIELD_MASK: Self::BitsType = (1 << Self::MANTISSA_FIELD_WIDTH) - 1;
58 const IMPLICIT_MANTISSA_BIT: Self::BitsType = 1 << Self::MANTISSA_FIELD_WIDTH;
59 const ZERO_SUBNORMAL_EXPONENT: Self::BitsType = 0;
60 const NAN_INFINITY_EXPONENT: Self::BitsType = (1 << Self::EXPONENT_FIELD_WIDTH) - 1;
61 const INFINITY_BITS: Self::BitsType =
62 Self::NAN_INFINITY_EXPONENT << Self::EXPONENT_FIELD_SHIFT;
63 const NAN_BITS: Self::BitsType =
64 Self::INFINITY_BITS | (1 << (Self::MANTISSA_FIELD_WIDTH - 1));
65 }
66 };
67 }
68
69 impl_float_encoding! {
70 impl FloatEncoding for F16 {
71 const EXPONENT_FIELD_WIDTH: u32 = 5;
72 const MANTISSA_FIELD_WIDTH: u32 = 10;
73 }
74 }
75
76 impl_float_encoding! {
77 impl FloatEncoding for f32 {
78 const EXPONENT_FIELD_WIDTH: u32 = 8;
79 const MANTISSA_FIELD_WIDTH: u32 = 23;
80 }
81 }
82
83 impl_float_encoding! {
84 impl FloatEncoding for f64 {
85 const EXPONENT_FIELD_WIDTH: u32 = 11;
86 const MANTISSA_FIELD_WIDTH: u32 = 52;
87 }
88 }