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}