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