float_format/
format.rs

1use crate::*;
2
3/// Format of the float, storing the number of bit for each fields.
4#[derive(derivative::Derivative, Clone)]
5#[derivative(Debug, PartialEq, Eq)]
6pub struct Format {
7    /// Whether the float is signed or not, if true a bit will be assigned for the sign.
8    pub signed: bool,
9
10    /// Number of bits for the exponent.
11    /// Currently support up to 31 bits only.
12    pub exp: u8,
13
14    /// Number of bits for the mantissa (significand).
15    pub mant: usize,
16
17    /// The excess (offset, biased) value for the exponent.
18    /// This is the value that is subtracted from the exponent to get the actual exponent.
19    pub excess: u32,
20
21    #[derivative(Debug = "ignore", PartialEq = "ignore")]
22    pub interpret: Interpret,
23}
24
25impl Format {
26    /// Create from the given values for `exp`, `mant`, and `excess`, default to signed.
27    pub fn new(exp: u8, mant: usize, excess: u32) -> Format {
28        if exp > 31 {
29            panic!("exponent bits must be less than 32");
30        }
31
32        Format {
33            signed: true,
34            exp,
35            mant,
36            excess,
37            interpret: |_| None,
38        }
39    }
40
41    /// Create from the given values for `exp`, `mant`, and `excess`, default to unsigned.
42    pub fn new_unsigned(exp: u8, mant: usize, excess: u32) -> Format {
43        if exp > 31 {
44            panic!("exponent bits must be less than 32");
45        }
46
47        Format {
48            signed: false,
49            exp,
50            mant,
51            excess,
52            interpret: |_| None,
53        }
54    }
55
56    /// Create from the given values for `signed`, `exp`, `mant`, and `excess`.
57    pub fn new_with_sign(signed: bool, exp: u8, mant: usize, excess: u32) -> Format {
58        if exp > 31 {
59            panic!("exponent bits must be less than 32");
60        }
61        
62        Format {
63            signed,
64            exp,
65            mant,
66            excess,
67            interpret: |_| None,
68        }
69    }
70
71    /// Create from the given values for `exp` and `mant`, default to signed.
72    /// The excess value is set to `(1 << (exp - 1)) - 1` (1 less than 2 to the power of `exp` - 1).
73    pub fn new_ieee_excess(exp: u8, mant: usize) -> Format {
74        if exp > 31 {
75            panic!("exponent bits must be less than 32");
76        }
77        
78        Format {
79            signed: true,
80            exp,
81            mant,
82            excess: (1 << (exp - 1)) - 1,
83            interpret: |_| None,
84        }
85    }
86
87    /// Create from the given values for `signed`, `exp`, and `mant`.
88    /// The excess value is set to `(1 << (exp - 1)) - 1` (1 less than 2 to the power of `exp` - 1).
89    pub fn new_ieee_excess_with_sign(signed: bool, exp: u8, mant: usize) -> Format {
90        if exp > 31 {
91            panic!("exponent bits must be less than 32");
92        }
93        
94        Format {
95            signed,
96            exp,
97            mant,
98            excess: (1 << (exp - 1)) - 1,
99            interpret: |_| None,
100        }
101    }
102
103    /// Get the number of bits for the format.
104    pub fn len(&self) -> usize {
105        self.signed as usize + self.exp as usize + self.mant
106    }
107}
108
109impl IeeeBinary for Format {
110    /// The exponent is 8 bits and biased by 127, and the mantissa is 23 bits.
111    fn ieee_binary32() -> Self {
112        Self {
113            interpret: Interpret::ieee_binary32(),
114            ..Self::new(8, 23, 127)
115        }
116    }
117    
118    /// The exponent is 11 bits and biased by 1023, and the mantissa is 52 bits.
119    fn ieee_binary64() -> Self {
120        Self {
121            interpret: Interpret::ieee_binary64(),
122            ..Self::new(11, 52, 1023)
123        }
124    }
125}