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)]
69mod tests {
70  use super::*;
71
72  /*#[test]
73  fn zero() {
74    assert_eq!(Posit::<8,   2, i8  >::ZERO.to_bits(), 0);
75    assert_eq!(Posit::<16,  2, i16 >::ZERO.to_bits(), 0);
76    assert_eq!(Posit::<32,  2, i32 >::ZERO.to_bits(), 0);
77    assert_eq!(Posit::<64,  2, i64 >::ZERO.to_bits(), 0);
78    assert_eq!(Posit::<128, 2, i128>::ZERO.to_bits(), 0);
79
80    assert_eq!(Posit::<8,   0, i8  >::ZERO.to_bits(), 0);
81    assert_eq!(Posit::<16,  1, i16 >::ZERO.to_bits(), 0);
82    assert_eq!(Posit::<32,  2, i32 >::ZERO.to_bits(), 0);
83    assert_eq!(Posit::<64,  3, i64 >::ZERO.to_bits(), 0);
84    assert_eq!(Posit::<128, 4, i128>::ZERO.to_bits(), 0);
85
86    assert_eq!(Posit::<6, 1, i8>::ZERO.to_bits(), 0);
87    assert_eq!(Posit::<10, 2, i64>::ZERO.to_bits(), 0);
88    assert_eq!(Posit::<32, 2, i64>::ZERO.to_bits(), 0);
89  }*/
90
91  use malachite::rational::Rational;
92
93  #[test]
94  fn zero() {
95    assert_eq!(
96      Posit::<16, 2, i16>::ZERO.to_bits_unsigned(),
97      0,
98    );
99    assert_eq!(
100      Posit::<10, 1, i16>::ZERO.to_bits_unsigned(),
101      0,
102    );
103    assert_eq!(
104      Rational::try_from(Posit::<10, 1, i16>::ZERO),
105      Ok(Rational::from(0)),
106    );
107  }
108
109  #[test]
110  fn nar() {
111    assert_eq!(
112      Posit::<16, 2, i16>::NAR.to_bits_unsigned(),
113      0b1000_0000_0000_0000,
114    );
115    assert_eq!(
116      Posit::<10, 1, i16>::NAR.to_bits_unsigned(),
117      0b111111_10_0000_0000,
118    );
119    assert_eq!(
120      Rational::try_from(Posit::<10, 1, i16>::NAR),
121      Err(super::rational::IsNaR),
122    );
123  }
124
125  #[test]
126  fn min_positive() {
127    assert_eq!(
128      Posit::<16, 2, i16>::MIN_POSITIVE.to_bits_unsigned(),
129      0b0000_0000_0000_0001,
130    );
131    assert_eq!(
132      Posit::<10, 1, i16>::MIN_POSITIVE.to_bits_unsigned(),
133      0b000000_00_0000_0001,
134    );
135    assert_eq!(
136      Rational::try_from(Posit::<10, 1, i16>::MIN_POSITIVE),
137      Ok(Rational::from_signeds(1, (1i64 << 2).pow(10 - 2))),
138    );
139  }
140
141  #[test]
142  fn max() {
143    assert_eq!(
144      Posit::<16, 2, i16>::MAX.to_bits_unsigned(),
145      0b0111_1111_1111_1111,
146    );
147    assert_eq!(
148      Posit::<10, 1, i16>::MAX.to_bits_unsigned(),
149      0b000000_01_1111_1111,
150    );
151    assert_eq!(
152      Rational::try_from(Posit::<10, 1, i16>::MAX),
153      Ok(Rational::from((1i64 << 2).pow(10 - 2))),
154    );
155  }
156
157  #[test]
158  fn max_negative() {
159    assert_eq!(
160      Posit::<16, 2, i16>::MAX_NEGATIVE.to_bits_unsigned(),
161      0b1111_1111_1111_1111,
162    );
163    assert_eq!(
164      Posit::<10, 1, i16>::MAX_NEGATIVE.to_bits_unsigned(),
165      0b111111_11_1111_1111,
166    );
167    assert_eq!(
168      Rational::try_from(Posit::<10, 1, i16>::MAX_NEGATIVE),
169      Ok(-Rational::from_signeds(1, (1i64 << 2).pow(10 - 2))),
170    );
171  }
172
173  #[test]
174  fn min() {
175    assert_eq!(
176      Posit::<16, 2, i16>::MIN.to_bits_unsigned(),
177      0b1000_0000_0000_0001,
178    );
179    assert_eq!(
180      Posit::<10, 1, i16>::MIN.to_bits_unsigned(),
181      0b111111_10_0000_0001,
182    );
183    assert_eq!(
184      Rational::try_from(Posit::<10, 1, i16>::MIN),
185      Ok(-Rational::from((1i64 << 2).pow(10 - 2))),
186    );
187  }
188
189  #[test]
190  fn one() {
191    assert_eq!(
192      Posit::<16, 2, i16>::ONE.to_bits_unsigned(),
193      0b0100_0000_0000_0000,
194    );
195    assert_eq!(
196      Posit::<10, 1, i16>::ONE.to_bits_unsigned(),
197      0b000000_01_0000_0000,
198    );
199    assert_eq!(
200      Rational::try_from(Posit::<10, 1, i16>::ONE),
201      Ok(Rational::from(1)),
202    );
203  }
204
205  #[test]
206  fn minus_one() {
207    assert_eq!(
208      Posit::<16, 2, i16>::MINUS_ONE.to_bits_unsigned(),
209      0b1100_0000_0000_0000,
210    );
211    assert_eq!(
212      Posit::<10, 1, i16>::MINUS_ONE.to_bits_unsigned(),
213      0b111111_11_0000_0000,
214    );
215    assert_eq!(
216      Rational::try_from(Posit::<10, 1, i16>::MINUS_ONE),
217      Ok(-Rational::from(1)),
218    );
219  }
220
221  /// Aux function: the max value of an n-bit posit with 2-bit exponent (as per the standard).
222  /// max = -min = 1/min_positive = -1/max_negative.
223  fn std_max(n: u32) -> Rational {
224    use malachite::base::num::arithmetic::traits::PowerOf2;
225    let n = i64::from(n);
226    Rational::power_of_2(4*n - 8)
227  }
228
229  macro_rules! std_tests {
230    ($t:ident) => {
231      mod $t {
232        use super::*;
233        use malachite::base::num::arithmetic::traits::Reciprocal;
234
235        #[test]
236        fn zero() {
237          assert_eq!(crate::$t::ZERO.try_into(), Ok(Rational::from(0)));
238        }
239
240        #[test]
241        fn nar() {
242          assert_eq!(Rational::try_from(crate::$t::NAR), Err(super::rational::IsNaR));
243        }
244
245        #[test]
246        fn min_positive() {
247          assert_eq!(crate::$t::MIN_POSITIVE.try_into(), Ok(std_max(crate::$t::BITS).reciprocal()));
248        }
249
250        #[test]
251        fn max() {
252          assert_eq!(crate::$t::MAX.try_into(), Ok(std_max(crate::$t::BITS)));
253        }
254
255        #[test]
256        fn max_negative() {
257          assert_eq!(crate::$t::MAX_NEGATIVE.try_into(), Ok(-std_max(crate::$t::BITS).reciprocal()));
258        }
259
260        #[test]
261        fn min() {
262          assert_eq!(crate::$t::MIN.try_into(), Ok(-std_max(crate::$t::BITS)));
263        }
264
265        #[test]
266        fn one() {
267          assert_eq!(crate::$t::ONE.try_into(), Ok(Rational::from(1)));
268        }
269
270        #[test]
271        fn minus_one() {
272          assert_eq!(crate::$t::MINUS_ONE.try_into(), Ok(-Rational::from(1)));
273        }
274      }
275    };
276  }
277
278  std_tests!{p8}
279  std_tests!{p16}
280  std_tests!{p32}
281  std_tests!{p64}
282}