fast_posit/posit/
consts.rs

1use super::*;
2use crate::underlying::const_as;
3
4impl<
5  const N: u32,
6  const ES: u32,
7  Int: crate::Int,
8> Posit<N, ES, Int> {
9  /// Zero (`0`), the additive identity element.
10  pub const ZERO: Self = Self(Int::ZERO);
11
12  /// NAR is the `0b1000...` bit pattern, appropriately sign-extended. This is that number
13  /// represented as an i128 (max width of any Int).
14  const NAR_I128: i128 = i128::MIN >> (128 - Int::BITS + Self::JUNK_BITS);
15
16  /// Not-a-real (`NaR`).
17  //
18  // Represented by the bit pattern `0b1000...0`.
19  pub const NAR: Self = Self(const_as(Self::NAR_I128));
20
21  /// One (`1`), the additive identity element.
22  //
23  // Represented by the bit pattern `0b0100...0`.
24  pub const ONE: Self = Self(const_as(-(Self::NAR_I128 >> 1)));
25
26  /// Negative one (`-1`).
27  //
28  // Represented by the bit pattern `0b1100...0`.
29  pub const MINUS_ONE: Self = Self(const_as(Self::NAR_I128 >> 1));
30
31  /// Largest representable value, equal to `-MIN`.
32  //
33  // Represented by the bit pattern `0b0111...1`.
34  pub const MAX: Self = Self(const_as(!Self::NAR_I128));
35
36  /// Smallest representable value, equal to `-MAX`.
37  ///
38  /// Not to be confused with the smallest *absolute value*, i.e. [`Self::MIN_POSITIVE`].
39  //
40  // Represented by the bit pattern `0b100...01`.
41  pub const MIN: Self = Self(const_as(Self::NAR_I128 + 1));
42
43  /// Smallest *positive* value, equal to `-MAX_NEGATIVE`.
44  //
45  // Represented by the bit pattern `0b000...01`.
46  pub const MIN_POSITIVE: Self = Self(Int::ONE);
47
48  /// Largest *negative* value, equal to `-MIN_POSITIVE`.
49  //
50  // Represented by the bit pattern `0b1111...1`.
51  pub const MAX_NEGATIVE: Self = Self(const_as(-1));
52
53  /// The minimum exponent; [`Self::MIN_POSITIVE`] = 2 <sup>[`Self::MIN_EXP`]</sup>.
54  pub const MIN_EXP: Int = {
55    let max_regime = N as i128 - 2;
56    let min_exp = -(max_regime << ES);
57    const_as(min_exp)
58  };
59
60  /// The maximum exponent; [`Self::MAX_NEGATIVE`] = 2 <sup>[`Self::MAX_EXP`]</sup>.
61  pub const MAX_EXP: Int = {
62    let max_regime = N as i128 - 2;
63    let max_exp = max_regime << ES;
64    const_as(max_exp)
65  };
66}
67
68#[cfg(test)]
69#[allow(overflowing_literals)]
70mod tests {
71  use super::*;
72
73  /*#[test]
74  fn zero() {
75    assert_eq!(Posit::<8,   2, i8  >::ZERO.to_bits(), 0);
76    assert_eq!(Posit::<16,  2, i16 >::ZERO.to_bits(), 0);
77    assert_eq!(Posit::<32,  2, i32 >::ZERO.to_bits(), 0);
78    assert_eq!(Posit::<64,  2, i64 >::ZERO.to_bits(), 0);
79    assert_eq!(Posit::<128, 2, i128>::ZERO.to_bits(), 0);
80
81    assert_eq!(Posit::<8,   0, i8  >::ZERO.to_bits(), 0);
82    assert_eq!(Posit::<16,  1, i16 >::ZERO.to_bits(), 0);
83    assert_eq!(Posit::<32,  2, i32 >::ZERO.to_bits(), 0);
84    assert_eq!(Posit::<64,  3, i64 >::ZERO.to_bits(), 0);
85    assert_eq!(Posit::<128, 4, i128>::ZERO.to_bits(), 0);
86
87    assert_eq!(Posit::<6, 1, i8>::ZERO.to_bits(), 0);
88    assert_eq!(Posit::<10, 2, i64>::ZERO.to_bits(), 0);
89    assert_eq!(Posit::<32, 2, i64>::ZERO.to_bits(), 0);
90  }*/
91
92  use malachite::rational::Rational;
93
94  #[test]
95  fn zero() {
96    assert_eq!(
97      Posit::<16, 2, i16>::ZERO.to_bits(),
98      0,
99    );
100    assert_eq!(
101      Posit::<10, 1, i16>::ZERO.to_bits(),
102      0,
103    );
104    assert_eq!(
105      Rational::try_from(Posit::<10, 1, i16>::ZERO),
106      Ok(Rational::from(0)),
107    );
108  }
109
110  #[test]
111  fn nar() {
112    assert_eq!(
113      Posit::<16, 2, i16>::NAR.to_bits(),
114      0b1000_0000_0000_0000,
115    );
116    assert_eq!(
117      Posit::<10, 1, i16>::NAR.to_bits(),
118      0b111111_10_0000_0000,
119    );
120    assert_eq!(
121      Rational::try_from(Posit::<10, 1, i16>::NAR),
122      Err(super::rational::IsNaR),
123    );
124  }
125
126  #[test]
127  fn min_positive() {
128    assert_eq!(
129      Posit::<16, 2, i16>::MIN_POSITIVE.to_bits(),
130      0b0000_0000_0000_0001,
131    );
132    assert_eq!(
133      Posit::<10, 1, i16>::MIN_POSITIVE.to_bits(),
134      0b000000_00_0000_0001,
135    );
136    assert_eq!(
137      Rational::try_from(Posit::<10, 1, i16>::MIN_POSITIVE),
138      Ok(Rational::from_signeds(1, (1i64 << 2).pow(10 - 2))),
139    );
140  }
141
142  #[test]
143  fn max() {
144    assert_eq!(
145      Posit::<16, 2, i16>::MAX.to_bits(),
146      0b0111_1111_1111_1111,
147    );
148    assert_eq!(
149      Posit::<10, 1, i16>::MAX.to_bits(),
150      0b000000_01_1111_1111,
151    );
152    assert_eq!(
153      Rational::try_from(Posit::<10, 1, i16>::MAX),
154      Ok(Rational::from((1i64 << 2).pow(10 - 2))),
155    );
156  }
157
158  #[test]
159  fn max_negative() {
160    assert_eq!(
161      Posit::<16, 2, i16>::MAX_NEGATIVE.to_bits(),
162      0b1111_1111_1111_1111,
163    );
164    assert_eq!(
165      Posit::<10, 1, i16>::MAX_NEGATIVE.to_bits(),
166      0b111111_11_1111_1111,
167    );
168    assert_eq!(
169      Rational::try_from(Posit::<10, 1, i16>::MAX_NEGATIVE),
170      Ok(-Rational::from_signeds(1, (1i64 << 2).pow(10 - 2))),
171    );
172  }
173
174  #[test]
175  fn min() {
176    assert_eq!(
177      Posit::<16, 2, i16>::MIN.to_bits(),
178      0b1000_0000_0000_0001,
179    );
180    assert_eq!(
181      Posit::<10, 1, i16>::MIN.to_bits(),
182      0b111111_10_0000_0001,
183    );
184    assert_eq!(
185      Rational::try_from(Posit::<10, 1, i16>::MIN),
186      Ok(-Rational::from((1i64 << 2).pow(10 - 2))),
187    );
188  }
189
190  #[test]
191  fn one() {
192    assert_eq!(
193      Posit::<16, 2, i16>::ONE.to_bits(),
194      0b0100_0000_0000_0000,
195    );
196    assert_eq!(
197      Posit::<10, 1, i16>::ONE.to_bits(),
198      0b000000_01_0000_0000,
199    );
200    assert_eq!(
201      Rational::try_from(Posit::<10, 1, i16>::ONE),
202      Ok(Rational::from(1)),
203    );
204  }
205
206  #[test]
207  fn minus_one() {
208    assert_eq!(
209      Posit::<16, 2, i16>::MINUS_ONE.to_bits(),
210      0b1100_0000_0000_0000,
211    );
212    assert_eq!(
213      Posit::<10, 1, i16>::MINUS_ONE.to_bits(),
214      0b111111_11_0000_0000,
215    );
216    assert_eq!(
217      Rational::try_from(Posit::<10, 1, i16>::MINUS_ONE),
218      Ok(-Rational::from(1)),
219    );
220  }
221
222  /// Aux function: the max value of an n-bit posit with 2-bit exponent (as per the standard).
223  /// max = -min = 1/min_positive = -1/max_negative.
224  fn std_max(n: u32) -> Rational {
225    use malachite::base::num::arithmetic::traits::PowerOf2;
226    let n = i64::from(n);
227    Rational::power_of_2(4*n - 8)
228  }
229
230  macro_rules! std_tests {
231    ($t:ident) => {
232      mod $t {
233        use super::*;
234        use malachite::base::num::arithmetic::traits::Reciprocal;
235
236        #[test]
237        fn zero() {
238          assert_eq!(crate::$t::ZERO.try_into(), Ok(Rational::from(0)));
239        }
240
241        #[test]
242        fn nar() {
243          assert_eq!(Rational::try_from(crate::$t::NAR), Err(super::rational::IsNaR));
244        }
245
246        #[test]
247        fn min_positive() {
248          assert_eq!(crate::$t::MIN_POSITIVE.try_into(), Ok(std_max(crate::$t::BITS).reciprocal()));
249        }
250
251        #[test]
252        fn max() {
253          assert_eq!(crate::$t::MAX.try_into(), Ok(std_max(crate::$t::BITS)));
254        }
255
256        #[test]
257        fn max_negative() {
258          assert_eq!(crate::$t::MAX_NEGATIVE.try_into(), Ok(-std_max(crate::$t::BITS).reciprocal()));
259        }
260
261        #[test]
262        fn min() {
263          assert_eq!(crate::$t::MIN.try_into(), Ok(-std_max(crate::$t::BITS)));
264        }
265
266        #[test]
267        fn one() {
268          assert_eq!(crate::$t::ONE.try_into(), Ok(Rational::from(1)));
269        }
270
271        #[test]
272        fn minus_one() {
273          assert_eq!(crate::$t::MINUS_ONE.try_into(), Ok(-Rational::from(1)));
274        }
275      }
276    };
277  }
278
279  std_tests!{p8}
280  std_tests!{p16}
281  std_tests!{p32}
282  std_tests!{p64}
283}