1use super::*;
2use crate::underlying::const_as;
3
4impl<
5 const N: u32,
6 const ES: u32,
7 Int: crate::Int,
8 const RS: u32,
9> Posit<N, ES, Int, RS> {
10 pub const ZERO: Self = Self(Int::ZERO);
12
13 const NAR_I128: i128 = i128::MIN >> (128 - Int::BITS + Self::JUNK_BITS);
16
17 pub const NAR: Self = Self(const_as(Self::NAR_I128));
21
22 pub const ONE: Self = Self(const_as(-(Self::NAR_I128 >> 1)));
26
27 pub const MINUS_ONE: Self = Self(const_as(Self::NAR_I128 >> 1));
31
32 pub const MAX: Self = Self(const_as(!Self::NAR_I128));
36
37 pub const MIN: Self = Self(const_as(Self::NAR_I128 + 1));
43
44 pub const MIN_POSITIVE: Self = Self(Int::ONE);
48
49 pub const MAX_NEGATIVE: Self = Self(const_as(-1));
53
54 pub const INT_MAX: Int = Self::int_max();
69
70 const fn int_max() -> Int {
71 let mut power = 0;
102 while power < Int::BITS {
103 let regime = power >> ES;
104 if Self::BITS < regime + ES + 3 {
106 return const_as::<i128, Int>(1 << power)
107 }
108 let fraction_bits = Self::BITS - regime - ES - 3;
111 if fraction_bits < power {
112 return const_as::<i128, Int>(1 << power)
113 }
114 power += 1
115 }
116 unreachable!()
117 }
118
119 pub(crate) const MAX_REGIME: u32 = {
124 if RS >= N - 2 {N - 2} else {RS}
125 };
126
127 pub(crate) const MAX_EXP: Int = {
130 let max_regime = Self::MAX_REGIME as i128;
131 let max_exp = max_regime << ES;
132 const_as(max_exp)
133 };
134}
135
136#[cfg(test)]
137#[allow(overflowing_literals)]
138mod tests {
139 use super::*;
140
141 use malachite::rational::Rational;
142
143 #[test]
144 fn zero() {
145 assert_eq!(
146 Posit::<16, 2, i16>::ZERO.to_bits(),
147 0,
148 );
149 assert_eq!(
150 Posit::<10, 1, i16>::ZERO.to_bits(),
151 0,
152 );
153 assert_eq!(
154 Rational::try_from(Posit::<10, 1, i16>::ZERO),
155 Ok(Rational::from(0)),
156 );
157 assert_eq!(
158 Posit::<16, 5, i16, 6>::ZERO.to_bits(),
159 0,
160 );
161 }
162
163 #[test]
164 fn nar() {
165 assert_eq!(
166 Posit::<16, 2, i16>::NAR.to_bits(),
167 0b1000_0000_0000_0000,
168 );
169 assert_eq!(
170 Posit::<10, 1, i16>::NAR.to_bits(),
171 0b111111_10_0000_0000,
172 );
173 assert_eq!(
174 Rational::try_from(Posit::<10, 1, i16>::NAR),
175 Err(super::rational::IsNaR),
176 );
177 assert_eq!(
178 Posit::<16, 5, i16, 6>::NAR.to_bits(),
179 0b1000_0000_0000_0000,
180 );
181 }
182
183 #[test]
184 fn min_positive() {
185 assert_eq!(
186 Posit::<16, 2, i16>::MIN_POSITIVE.to_bits(),
187 0b0000_0000_0000_0001,
188 );
189 assert_eq!(
190 Posit::<10, 1, i16>::MIN_POSITIVE.to_bits(),
191 0b000000_00_0000_0001,
192 );
193 assert_eq!(
194 Rational::try_from(Posit::<10, 1, i16>::MIN_POSITIVE),
195 Ok(Rational::from_signeds(1, (1i64 << 2).pow(10 - 2))),
196 );
197 assert_eq!(
198 Posit::<16, 5, i16, 6>::MIN_POSITIVE.to_bits(),
199 0b000000_00_0000_0001,
200 );
201 }
202
203 #[test]
204 fn max() {
205 assert_eq!(
206 Posit::<16, 2, i16>::MAX.to_bits(),
207 0b0111_1111_1111_1111,
208 );
209 assert_eq!(
210 Posit::<10, 1, i16>::MAX.to_bits(),
211 0b000000_01_1111_1111,
212 );
213 assert_eq!(
214 Rational::try_from(Posit::<10, 1, i16>::MAX),
215 Ok(Rational::from((1i64 << 2).pow(10 - 2))),
216 );
217 assert_eq!(
218 Posit::<16, 5, i16, 6>::MAX.to_bits(),
219 0b0111_1111_1111_1111,
220 );
221 }
222
223 #[test]
224 fn max_negative() {
225 assert_eq!(
226 Posit::<16, 2, i16>::MAX_NEGATIVE.to_bits(),
227 0b1111_1111_1111_1111,
228 );
229 assert_eq!(
230 Posit::<10, 1, i16>::MAX_NEGATIVE.to_bits(),
231 0b111111_11_1111_1111,
232 );
233 assert_eq!(
234 Rational::try_from(Posit::<10, 1, i16>::MAX_NEGATIVE),
235 Ok(-Rational::from_signeds(1, (1i64 << 2).pow(10 - 2))),
236 );
237 assert_eq!(
238 Posit::<16, 5, i16, 6>::MAX_NEGATIVE.to_bits(),
239 0b1111_1111_1111_1111,
240 );
241 }
242
243 #[test]
244 fn min() {
245 assert_eq!(
246 Posit::<16, 2, i16>::MIN.to_bits(),
247 0b1000_0000_0000_0001,
248 );
249 assert_eq!(
250 Posit::<10, 1, i16>::MIN.to_bits(),
251 0b111111_10_0000_0001,
252 );
253 assert_eq!(
254 Rational::try_from(Posit::<10, 1, i16>::MIN),
255 Ok(-Rational::from((1i64 << 2).pow(10 - 2))),
256 );
257 assert_eq!(
258 Posit::<16, 5, i16, 6>::MIN.to_bits(),
259 0b1000_0000_0000_0001,
260 );
261 }
262
263 #[test]
264 fn one() {
265 assert_eq!(
266 Posit::<16, 2, i16>::ONE.to_bits(),
267 0b0100_0000_0000_0000,
268 );
269 assert_eq!(
270 Posit::<10, 1, i16>::ONE.to_bits(),
271 0b000000_01_0000_0000,
272 );
273 assert_eq!(
274 Rational::try_from(Posit::<10, 1, i16>::ONE),
275 Ok(Rational::from(1)),
276 );
277 assert_eq!(
278 Posit::<16, 5, i16, 6>::ONE.to_bits(),
279 0b0100_0000_0000_0000,
280 );
281 }
282
283 #[test]
284 fn minus_one() {
285 assert_eq!(
286 Posit::<16, 2, i16>::MINUS_ONE.to_bits(),
287 0b1100_0000_0000_0000,
288 );
289 assert_eq!(
290 Posit::<10, 1, i16>::MINUS_ONE.to_bits(),
291 0b111111_11_0000_0000,
292 );
293 assert_eq!(
294 Rational::try_from(Posit::<10, 1, i16>::MINUS_ONE),
295 Ok(-Rational::from(1)),
296 );
297 assert_eq!(
298 Posit::<16, 5, i16, 6>::MINUS_ONE.to_bits(),
299 0b1100_0000_0000_0000,
300 );
301 }
302
303 #[test]
304 fn int_max() {
305 fn b_exhaustive<const N: u32, const ES: u32, Int: crate::Int, const RS: u32>() {
306 use crate::RoundInto;
307 let int_max: i32 = const_as(Posit::<N, ES, Int>::INT_MAX);
309 for int in 0 ..= int_max {
310 let posit: Posit::<N, ES, Int> = int.round_into();
311 let re_int: i32 = posit.round_into();
312 assert_eq!(int, re_int)
313 }
314 let int_invalid: i32 = int_max + 1;
316 let posit_invalid: Posit::<N, ES, Int> = int_invalid.round_into();
317 let re_int_invalid: i32 = posit_invalid.round_into();
318 assert_ne!(int_invalid, re_int_invalid)
319 }
320 fn exhaustive<const N: u32, const ES: u32, Int: crate::Int>() {
321 b_exhaustive::<N, ES, Int, N>()
322 }
323
324 exhaustive::<10, 0, i16>();
325 exhaustive::<10, 1, i16>();
326 exhaustive::<10, 2, i16>();
327 exhaustive::<10, 3, i16>();
328 exhaustive::<8, 0, i8>();
329 exhaustive::<8, 2, i8>();
330 exhaustive::<16, 2, i16>();
331 exhaustive::<32, 2, i32>();
332 exhaustive::<3, 0, i8>();
333 exhaustive::<4, 0, i8>();
334 exhaustive::<4, 1, i8>();
335 b_exhaustive::<8, 3, i8, 6>();
336 b_exhaustive::<16, 5, i16, 6>();
337 b_exhaustive::<20, 5, i32, 6>();
338 }
339
340 fn std_max(n: u32) -> Rational {
343 use malachite::base::num::arithmetic::traits::PowerOf2;
344 let n = i64::from(n);
345 Rational::power_of_2(4*n - 8)
346 }
347
348 macro_rules! std_tests {
349 ($t:ident) => {
350 mod $t {
351 use super::*;
352 use malachite::base::num::arithmetic::traits::Reciprocal;
353
354 #[test]
355 fn zero() {
356 assert_eq!(crate::$t::ZERO.try_into(), Ok(Rational::from(0)));
357 }
358
359 #[test]
360 fn nar() {
361 assert_eq!(Rational::try_from(crate::$t::NAR), Err(super::rational::IsNaR));
362 }
363
364 #[test]
365 fn min_positive() {
366 assert_eq!(crate::$t::MIN_POSITIVE.try_into(), Ok(std_max(crate::$t::BITS).reciprocal()));
367 }
368
369 #[test]
370 fn max() {
371 assert_eq!(crate::$t::MAX.try_into(), Ok(std_max(crate::$t::BITS)));
372 }
373
374 #[test]
375 fn max_negative() {
376 assert_eq!(crate::$t::MAX_NEGATIVE.try_into(), Ok(-std_max(crate::$t::BITS).reciprocal()));
377 }
378
379 #[test]
380 fn min() {
381 assert_eq!(crate::$t::MIN.try_into(), Ok(-std_max(crate::$t::BITS)));
382 }
383
384 #[test]
385 fn one() {
386 assert_eq!(crate::$t::ONE.try_into(), Ok(Rational::from(1)));
387 }
388
389 #[test]
390 fn minus_one() {
391 assert_eq!(crate::$t::MINUS_ONE.try_into(), Ok(-Rational::from(1)));
392 }
393 }
394 };
395 }
396
397 std_tests!{p8}
398 std_tests!{p16}
399 std_tests!{p32}
400 std_tests!{p64}
401}