algebraeon_nzq/integer/
mod.rs

1//! The Integer type and operations.
2
3use crate::Rational;
4use crate::natural::Natural;
5use crate::traits::{Abs, AbsDiff, DivMod};
6use algebraeon_sets::structure::{
7    CanonicalStructure, CountableSetSignature, EqSignature, MetaType, OrdSignature,
8    PartialOrdSignature, SetSignature, Signature, ToStringSignature,
9};
10use malachite_base::num::basic::traits::{One, Two, Zero};
11use std::iter::{Product, Sum};
12use std::{
13    ops::{Add, AddAssign, Div, Mul, MulAssign, Neg, Rem, Sub, SubAssign},
14    str::FromStr,
15};
16
17/// Represent an integer {..., -2, -1, 0, 1, 2, ...}
18#[derive(Default, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, CanonicalStructure)]
19#[canonical_structure(eq, partial_ord, ord)]
20pub struct Integer(malachite_nz::integer::Integer);
21
22#[allow(clippy::wrong_self_convention)]
23impl Integer {
24    pub(crate) fn from_malachite(value: malachite_nz::integer::Integer) -> Self {
25        Self(value)
26    }
27    pub(crate) fn to_malachite(self) -> malachite_nz::integer::Integer {
28        self.0
29    }
30    pub(crate) fn to_malachite_ref(&self) -> &malachite_nz::integer::Integer {
31        &self.0
32    }
33}
34
35impl ToStringSignature for IntegerCanonicalStructure {
36    fn to_string(&self, elem: &Self::Set) -> String {
37        format!("{}", elem)
38    }
39}
40
41impl std::fmt::Display for Integer {
42    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
43        self.0.fmt(f)
44    }
45}
46
47impl From<u8> for Integer {
48    fn from(value: u8) -> Self {
49        Self(malachite_nz::integer::Integer::from(value))
50    }
51}
52impl From<u16> for Integer {
53    fn from(value: u16) -> Self {
54        Self(malachite_nz::integer::Integer::from(value))
55    }
56}
57impl From<u32> for Integer {
58    fn from(value: u32) -> Self {
59        Self(malachite_nz::integer::Integer::from(value))
60    }
61}
62impl From<u64> for Integer {
63    fn from(value: u64) -> Self {
64        Self(malachite_nz::integer::Integer::from(value))
65    }
66}
67impl From<u128> for Integer {
68    fn from(value: u128) -> Self {
69        Self(malachite_nz::integer::Integer::from(value))
70    }
71}
72impl From<usize> for Integer {
73    fn from(value: usize) -> Self {
74        Self(malachite_nz::integer::Integer::from(value))
75    }
76}
77impl From<i8> for Integer {
78    fn from(value: i8) -> Self {
79        Self(malachite_nz::integer::Integer::from(value))
80    }
81}
82impl From<i16> for Integer {
83    fn from(value: i16) -> Self {
84        Self(malachite_nz::integer::Integer::from(value))
85    }
86}
87impl From<i32> for Integer {
88    fn from(value: i32) -> Self {
89        Self(malachite_nz::integer::Integer::from(value))
90    }
91}
92impl From<i64> for Integer {
93    fn from(value: i64) -> Self {
94        Self(malachite_nz::integer::Integer::from(value))
95    }
96}
97impl From<i128> for Integer {
98    fn from(value: i128) -> Self {
99        Self(malachite_nz::integer::Integer::from(value))
100    }
101}
102impl From<isize> for Integer {
103    fn from(value: isize) -> Self {
104        Self(malachite_nz::integer::Integer::from(value))
105    }
106}
107impl From<Natural> for Integer {
108    fn from(value: Natural) -> Self {
109        Self(malachite_nz::integer::Integer::from(value.to_malachite()))
110    }
111}
112impl From<&Natural> for Integer {
113    fn from(value: &Natural) -> Self {
114        Self(malachite_nz::integer::Integer::from(
115            value.to_malachite_ref(),
116        ))
117    }
118}
119impl From<&Integer> for Integer {
120    fn from(value: &Integer) -> Self {
121        value.clone()
122    }
123}
124
125impl TryFrom<Rational> for Integer {
126    type Error = ();
127    fn try_from(value: Rational) -> Result<Self, Self::Error> {
128        if let Ok(value) = malachite_nz::integer::Integer::try_from(value.to_malachite()) {
129            Ok(Integer::from_malachite(value))
130        } else {
131            Err(())
132        }
133    }
134}
135impl TryFrom<&Rational> for Integer {
136    type Error = ();
137    fn try_from(value: &Rational) -> Result<Self, Self::Error> {
138        if let Ok(value) = malachite_nz::integer::Integer::try_from(value.to_malachite_ref()) {
139            Ok(Integer::from_malachite(value))
140        } else {
141            Err(())
142        }
143    }
144}
145
146macro_rules! impl_try_into_unsigned {
147    ($($t:ty),*) => {
148        $(
149            impl TryInto<$t> for Integer {
150                type Error = ();
151
152                fn try_into(self) -> Result<$t, Self::Error> {
153                    (&self).try_into()
154                }
155            }
156            impl TryInto<$t> for &Integer {
157                type Error = ();
158
159                fn try_into(self) -> Result<$t, Self::Error> {
160                    if self < &Integer::ZERO {
161                        Err(())
162                    } else {
163                        if self > &Integer::from(<$t>::MAX) {
164                            Err(())
165                        } else {
166                            let limbs = self.to_malachite_ref().to_twos_complement_limbs_asc();
167                            match limbs.len() {
168                                0 => {
169                                    Ok(0)
170                                }
171                                1 => {
172                                    Ok(limbs[0] as $t)
173                                }
174                                2 | 3 => {
175                                    if limbs.len() == 3 {
176                                        debug_assert!(limbs[2] == 0); // malachite sometimes adds a 0 on the end for some reason
177                                    }
178                                    let low = limbs[0] as u128;
179                                    let high = limbs[1] as u128;
180                                    let value = (high << 64) | low;
181                                    Ok(value as $t)
182                                }
183                                _ => {unreachable!()}
184                            }
185                        }
186                    }
187                }
188            }
189        )*
190    };
191}
192
193macro_rules! impl_try_into_signed {
194    ($($t:ty),*) => {
195        $(
196            impl TryInto<$t> for Integer {
197                type Error = ();
198
199                fn try_into(self) -> Result<$t, Self::Error> {
200                    (&self).try_into()
201                }
202            }
203            impl TryInto<$t> for &Integer {
204                type Error = ();
205
206                fn try_into(self) -> Result<$t, Self::Error> {
207                    if self > &Integer::from(<$t>::MAX) {
208                        Err(())
209                    } else if self < &Integer::from(<$t>::MIN) {
210                        Err(())
211                    } else {
212                        let limbs = self.to_malachite_ref().to_twos_complement_limbs_asc();
213                        match limbs.len() {
214                            0 => {
215                                Ok(0)
216                            }
217                            1 => {
218                                Ok(limbs[0] as $t)
219                            }
220                            2 | 3 => {
221                                if limbs.len() == 3 {
222                                    debug_assert!(limbs[2] == 0); // malachite sometimes adds a 0 on the end for some reason
223                                }
224                                let low = limbs[0] as u128;
225                                let high = limbs[1] as u128;
226                                let value = (high << 64) | low;
227                                Ok(value as $t)
228                            }
229                            _ => {unreachable!()}
230                        }
231                    }
232                }
233            }
234        )*
235    };
236}
237
238impl_try_into_unsigned!(u8, u16, u32, u64, u128, usize);
239impl_try_into_signed!(i8, i16, i32, i64, i128, isize);
240
241#[allow(clippy::from_over_into, clippy::cast_precision_loss)]
242impl Into<f64> for Integer {
243    fn into(self) -> f64 {
244        if self < Integer::ZERO {
245            -<Self as Into<f64>>::into(-self)
246        } else {
247            let limbs = self.to_malachite().into_twos_complement_limbs_asc();
248            let mut flt = 0.0;
249            for (i, k) in limbs.into_iter().enumerate() {
250                flt += (k as f64) * (2.0_f64).powf(i as f64 * 64.0);
251            }
252            flt
253        }
254    }
255}
256#[allow(clippy::from_over_into)]
257impl Into<f64> for &Integer {
258    fn into(self) -> f64 {
259        self.clone().into()
260    }
261}
262#[allow(clippy::from_over_into)]
263impl Into<f32> for Integer {
264    fn into(self) -> f32 {
265        let x: f64 = self.into();
266        x as f32
267    }
268}
269#[allow(clippy::from_over_into)]
270impl Into<f32> for &Integer {
271    fn into(self) -> f32 {
272        self.clone().into()
273    }
274}
275
276impl FromStr for Integer {
277    type Err = ();
278
279    fn from_str(s: &str) -> Result<Self, Self::Err> {
280        Ok(Self(malachite_nz::integer::Integer::from_str(s)?))
281    }
282}
283
284impl Integer {
285    pub const ZERO: Self = Self(malachite_nz::integer::Integer::ZERO);
286    pub const ONE: Self = Self(malachite_nz::integer::Integer::ONE);
287    pub const TWO: Self = Self(malachite_nz::integer::Integer::TWO);
288
289    pub fn sqrt_if_square(&self) -> Option<Natural> {
290        if self < &Integer::ZERO {
291            None
292        } else {
293            self.abs().sqrt_if_square()
294        }
295    }
296
297    pub fn is_square(&self) -> bool {
298        if self < &Integer::ZERO {
299            false
300        } else {
301            self.abs().is_square()
302        }
303    }
304}
305
306impl PartialEq<Natural> for Integer {
307    fn eq(&self, other: &Natural) -> bool {
308        self.0.eq(other.to_malachite_ref())
309    }
310}
311impl PartialEq<&Natural> for Integer {
312    fn eq(&self, other: &&Natural) -> bool {
313        self.eq(*other)
314    }
315}
316impl PartialOrd<Natural> for Integer {
317    fn partial_cmp(&self, other: &Natural) -> Option<std::cmp::Ordering> {
318        self.0.partial_cmp(other.to_malachite_ref())
319    }
320}
321impl PartialOrd<&Natural> for Integer {
322    fn partial_cmp(&self, other: &&Natural) -> Option<std::cmp::Ordering> {
323        self.partial_cmp(*other)
324    }
325}
326
327impl AddAssign<Integer> for Integer {
328    fn add_assign(&mut self, rhs: Integer) {
329        self.0.add_assign(rhs.0);
330    }
331}
332impl AddAssign<&Integer> for Integer {
333    fn add_assign(&mut self, rhs: &Integer) {
334        self.0.add_assign(&rhs.0);
335    }
336}
337
338impl SubAssign<Integer> for Integer {
339    fn sub_assign(&mut self, rhs: Integer) {
340        self.0.sub_assign(rhs.0);
341    }
342}
343impl SubAssign<&Integer> for Integer {
344    fn sub_assign(&mut self, rhs: &Integer) {
345        self.0.sub_assign(&rhs.0);
346    }
347}
348
349impl MulAssign<Integer> for Integer {
350    fn mul_assign(&mut self, rhs: Integer) {
351        self.0.mul_assign(rhs.0);
352    }
353}
354impl MulAssign<&Integer> for Integer {
355    fn mul_assign(&mut self, rhs: &Integer) {
356        self.0.mul_assign(&rhs.0);
357    }
358}
359
360impl Neg for Integer {
361    type Output = Integer;
362
363    fn neg(self) -> Self::Output {
364        Integer(self.0.neg())
365    }
366}
367impl Neg for &Integer {
368    type Output = Integer;
369
370    fn neg(self) -> Self::Output {
371        Integer((&self.0).neg())
372    }
373}
374
375impl Add<Integer> for Integer {
376    type Output = Integer;
377
378    fn add(self, rhs: Integer) -> Self::Output {
379        Integer(self.0.add(rhs.0))
380    }
381}
382impl Add<&Integer> for Integer {
383    type Output = Integer;
384
385    fn add(self, rhs: &Integer) -> Self::Output {
386        Integer(self.0.add(&rhs.0))
387    }
388}
389impl Add<Integer> for &Integer {
390    type Output = Integer;
391
392    fn add(self, rhs: Integer) -> Self::Output {
393        Integer((&self.0).add(rhs.0))
394    }
395}
396impl Add<&Integer> for &Integer {
397    type Output = Integer;
398
399    fn add(self, rhs: &Integer) -> Self::Output {
400        Integer((&self.0).add(&rhs.0))
401    }
402}
403
404impl Sub<Integer> for Integer {
405    type Output = Integer;
406
407    fn sub(self, rhs: Integer) -> Self::Output {
408        Integer(self.0.sub(rhs.0))
409    }
410}
411impl Sub<&Integer> for Integer {
412    type Output = Integer;
413
414    fn sub(self, rhs: &Integer) -> Self::Output {
415        Integer(self.0.sub(&rhs.0))
416    }
417}
418impl Sub<Integer> for &Integer {
419    type Output = Integer;
420
421    fn sub(self, rhs: Integer) -> Self::Output {
422        Integer((&self.0).sub(rhs.0))
423    }
424}
425impl Sub<&Integer> for &Integer {
426    type Output = Integer;
427
428    fn sub(self, rhs: &Integer) -> Self::Output {
429        Integer((&self.0).sub(&rhs.0))
430    }
431}
432
433impl Mul<Integer> for Integer {
434    type Output = Integer;
435
436    fn mul(self, rhs: Integer) -> Self::Output {
437        Integer(self.0.mul(rhs.0))
438    }
439}
440impl Mul<&Integer> for Integer {
441    type Output = Integer;
442
443    fn mul(self, rhs: &Integer) -> Self::Output {
444        Integer(self.0.mul(&rhs.0))
445    }
446}
447impl Mul<Integer> for &Integer {
448    type Output = Integer;
449
450    fn mul(self, rhs: Integer) -> Self::Output {
451        Integer((&self.0).mul(rhs.0))
452    }
453}
454impl Mul<&Integer> for &Integer {
455    type Output = Integer;
456
457    fn mul(self, rhs: &Integer) -> Self::Output {
458        Integer((&self.0).mul(&rhs.0))
459    }
460}
461
462impl Rem<Integer> for Integer {
463    type Output = Integer;
464
465    fn rem(self, rhs: Integer) -> Self::Output {
466        use malachite_base::num::arithmetic::traits::Mod;
467        Integer(self.0.mod_op(rhs.0))
468    }
469}
470impl Rem<&Integer> for Integer {
471    type Output = Integer;
472
473    fn rem(self, rhs: &Integer) -> Self::Output {
474        use malachite_base::num::arithmetic::traits::Mod;
475        Integer(self.0.mod_op(&rhs.0))
476    }
477}
478impl Rem<Integer> for &Integer {
479    type Output = Integer;
480
481    fn rem(self, rhs: Integer) -> Self::Output {
482        use malachite_base::num::arithmetic::traits::Mod;
483        Integer((&self.0).mod_op(rhs.0))
484    }
485}
486impl Rem<&Integer> for &Integer {
487    type Output = Integer;
488
489    fn rem(self, rhs: &Integer) -> Self::Output {
490        use malachite_base::num::arithmetic::traits::Mod;
491        Integer((&self.0).mod_op(&rhs.0))
492    }
493}
494
495impl Rem<Natural> for Integer {
496    type Output = Natural;
497
498    fn rem(self, rhs: Natural) -> Self::Output {
499        self.rem(Integer::from(rhs)).abs()
500    }
501}
502impl Rem<&Natural> for Integer {
503    type Output = Natural;
504
505    fn rem(self, rhs: &Natural) -> Self::Output {
506        self.rem(Integer::from(rhs)).abs()
507    }
508}
509impl Rem<Natural> for &Integer {
510    type Output = Natural;
511
512    fn rem(self, rhs: Natural) -> Self::Output {
513        self.rem(Integer::from(rhs)).abs()
514    }
515}
516impl Rem<&Natural> for &Integer {
517    type Output = Natural;
518
519    fn rem(self, rhs: &Natural) -> Self::Output {
520        self.rem(Integer::from(rhs)).abs()
521    }
522}
523
524impl Div<Integer> for Integer {
525    type Output = Integer;
526
527    fn div(self, rhs: Integer) -> Self::Output {
528        Integer(self.0.div(rhs.0))
529    }
530}
531impl Div<&Integer> for Integer {
532    type Output = Integer;
533
534    fn div(self, rhs: &Integer) -> Self::Output {
535        Integer(self.0.div(&rhs.0))
536    }
537}
538impl Div<Integer> for &Integer {
539    type Output = Integer;
540
541    fn div(self, rhs: Integer) -> Self::Output {
542        Integer((&self.0).div(rhs.0))
543    }
544}
545impl Div<&Integer> for &Integer {
546    type Output = Integer;
547
548    fn div(self, rhs: &Integer) -> Self::Output {
549        Integer((&self.0).div(&rhs.0))
550    }
551}
552
553impl DivMod<Integer> for Integer {
554    type DivOutput = Integer;
555
556    type ModOutput = Integer;
557
558    fn div_mod(self, other: Integer) -> (Self::DivOutput, Self::ModOutput) {
559        use malachite_base::num::arithmetic::traits::DivMod;
560        let (q, r) = self.0.div_mod(other.0);
561        (Integer(q), Integer(r))
562    }
563}
564impl DivMod<&Integer> for Integer {
565    type DivOutput = Integer;
566
567    type ModOutput = Integer;
568
569    fn div_mod(self, other: &Integer) -> (Self::DivOutput, Self::ModOutput) {
570        use malachite_base::num::arithmetic::traits::DivMod;
571        let (q, r) = self.0.div_mod(&other.0);
572        (Integer(q), Integer(r))
573    }
574}
575impl DivMod<Integer> for &Integer {
576    type DivOutput = Integer;
577
578    type ModOutput = Integer;
579
580    fn div_mod(self, other: Integer) -> (Self::DivOutput, Self::ModOutput) {
581        use malachite_base::num::arithmetic::traits::DivMod;
582        let (q, r) = (&self.0).div_mod(other.0);
583        (Integer(q), Integer(r))
584    }
585}
586impl DivMod<&Integer> for &Integer {
587    type DivOutput = Integer;
588
589    type ModOutput = Integer;
590
591    fn div_mod(self, other: &Integer) -> (Self::DivOutput, Self::ModOutput) {
592        use malachite_base::num::arithmetic::traits::DivMod;
593        let (q, r) = (&self.0).div_mod(&other.0);
594        (Integer(q), Integer(r))
595    }
596}
597
598impl Abs for Integer {
599    type Output = Natural;
600    fn abs(self) -> Self::Output {
601        use malachite_base::num::arithmetic::traits::UnsignedAbs;
602        Natural::from_malachite(self.0.unsigned_abs())
603    }
604}
605
606impl Abs for &Integer {
607    type Output = Natural;
608    fn abs(self) -> Self::Output {
609        use malachite_base::num::arithmetic::traits::UnsignedAbs;
610        Natural::from_malachite((&self.0).unsigned_abs())
611    }
612}
613
614impl AbsDiff<Integer> for Integer {
615    type Output = Natural;
616
617    fn abs_diff(self, rhs: Integer) -> Self::Output {
618        use malachite_base::num::arithmetic::traits::AbsDiff;
619        Natural::from_malachite(self.0.abs_diff(rhs.0))
620    }
621}
622impl AbsDiff<&Integer> for Integer {
623    type Output = Natural;
624
625    fn abs_diff(self, rhs: &Integer) -> Self::Output {
626        use malachite_base::num::arithmetic::traits::AbsDiff;
627        Natural::from_malachite(self.0.abs_diff(&rhs.0))
628    }
629}
630impl AbsDiff<Integer> for &Integer {
631    type Output = Natural;
632
633    fn abs_diff(self, rhs: Integer) -> Self::Output {
634        use malachite_base::num::arithmetic::traits::AbsDiff;
635        Natural::from_malachite((&self.0).abs_diff(rhs.0))
636    }
637}
638impl AbsDiff<&Integer> for &Integer {
639    type Output = Natural;
640
641    fn abs_diff(self, rhs: &Integer) -> Self::Output {
642        use malachite_base::num::arithmetic::traits::AbsDiff;
643        Natural::from_malachite((&self.0).abs_diff(&rhs.0))
644    }
645}
646
647impl Sum for Integer {
648    fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
649        Self::from_malachite(malachite_nz::integer::Integer::sum(
650            iter.map(|x| x.to_malachite()),
651        ))
652    }
653}
654
655impl Product for Integer {
656    fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
657        Self::from_malachite(malachite_nz::integer::Integer::product(
658            iter.map(|x| x.to_malachite()),
659        ))
660    }
661}
662
663impl CountableSetSignature for IntegerCanonicalStructure {
664    fn generate_all_elements(&self) -> impl Iterator<Item = Self::Set> + Clone {
665        use malachite_nz::integer::exhaustive::exhaustive_integers;
666        exhaustive_integers().map(Integer::from_malachite)
667    }
668}
669
670#[cfg(test)]
671mod tests {
672    use super::*;
673
674    #[test]
675    fn test_int_to_uint() {
676        // u8
677        assert_eq!(
678            <&Integer as TryInto<u8>>::try_into(&Integer::from_str("0").unwrap()),
679            Ok(0)
680        );
681        assert_eq!(
682            <&Integer as TryInto<u8>>::try_into(&Integer::from_str("255").unwrap()),
683            Ok(255)
684        );
685        assert_eq!(
686            <&Integer as TryInto<u8>>::try_into(&Integer::from_str("256").unwrap()),
687            Err(())
688        );
689
690        // u16
691        assert_eq!(
692            <&Integer as TryInto<u16>>::try_into(&Integer::from_str("65535").unwrap()),
693            Ok(65535)
694        );
695        assert_eq!(
696            <&Integer as TryInto<u16>>::try_into(&Integer::from_str("65536").unwrap()),
697            Err(())
698        );
699
700        // u32
701        assert_eq!(
702            <&Integer as TryInto<u32>>::try_into(&Integer::from_str("4294967295").unwrap()),
703            Ok(4294967295)
704        );
705        assert_eq!(
706            <&Integer as TryInto<u32>>::try_into(&Integer::from_str("4294967296").unwrap()),
707            Err(())
708        );
709
710        // u64
711        assert_eq!(
712            <&Integer as TryInto<u64>>::try_into(
713                &Integer::from_str("18446744073709551615").unwrap()
714            ),
715            Ok(18446744073709551615)
716        );
717        assert_eq!(
718            <&Integer as TryInto<u64>>::try_into(
719                &Integer::from_str("18446744073709551616").unwrap()
720            ),
721            Err(())
722        );
723
724        // u128
725        assert_eq!(
726            <&Integer as TryInto<u128>>::try_into(
727                &Integer::from_str("340282366920938463463374607431768211455").unwrap()
728            ),
729            Ok(340282366920938463463374607431768211455)
730        );
731        assert_eq!(
732            <&Integer as TryInto<u128>>::try_into(
733                &Integer::from_str("340282366920938463463374607431768211456").unwrap()
734            ),
735            Err(())
736        );
737    }
738
739    #[test]
740    fn test_int_to_int() {
741        // i8
742        assert_eq!(
743            <&Integer as TryInto<i8>>::try_into(&Integer::from_str("-129").unwrap()),
744            Err(())
745        );
746        assert_eq!(
747            <&Integer as TryInto<i8>>::try_into(&Integer::from_str("-128").unwrap()),
748            Ok(-128)
749        );
750        assert_eq!(
751            <&Integer as TryInto<i8>>::try_into(&Integer::from_str("0").unwrap()),
752            Ok(0)
753        );
754        assert_eq!(
755            <&Integer as TryInto<i8>>::try_into(&Integer::from_str("127").unwrap()),
756            Ok(127)
757        );
758        assert_eq!(
759            <&Integer as TryInto<i8>>::try_into(&Integer::from_str("128").unwrap()),
760            Err(())
761        );
762
763        // i16
764        assert_eq!(
765            <&Integer as TryInto<i16>>::try_into(&Integer::from_str("-32769").unwrap()),
766            Err(())
767        );
768        assert_eq!(
769            <&Integer as TryInto<i16>>::try_into(&Integer::from_str("-32768").unwrap()),
770            Ok(-32768)
771        );
772        assert_eq!(
773            <&Integer as TryInto<i16>>::try_into(&Integer::from_str("32767").unwrap()),
774            Ok(32767)
775        );
776        assert_eq!(
777            <&Integer as TryInto<i16>>::try_into(&Integer::from_str("32768").unwrap()),
778            Err(())
779        );
780
781        // i32
782        assert_eq!(
783            <&Integer as TryInto<i32>>::try_into(&Integer::from_str("-2147483649").unwrap()),
784            Err(())
785        );
786        assert_eq!(
787            <&Integer as TryInto<i32>>::try_into(&Integer::from_str("-2147483648").unwrap()),
788            Ok(-2147483648)
789        );
790        assert_eq!(
791            <&Integer as TryInto<i32>>::try_into(&Integer::from_str("2147483647").unwrap()),
792            Ok(2147483647)
793        );
794        assert_eq!(
795            <&Integer as TryInto<i32>>::try_into(&Integer::from_str("2147483648").unwrap()),
796            Err(())
797        );
798
799        // i64
800        assert_eq!(
801            <&Integer as TryInto<i64>>::try_into(
802                &Integer::from_str("-9223372036854775809").unwrap()
803            ),
804            Err(())
805        );
806        assert_eq!(
807            <&Integer as TryInto<i64>>::try_into(
808                &Integer::from_str("-9223372036854775808").unwrap()
809            ),
810            Ok(-9223372036854775808)
811        );
812        assert_eq!(
813            <&Integer as TryInto<i64>>::try_into(
814                &Integer::from_str("9223372036854775807").unwrap()
815            ),
816            Ok(9223372036854775807)
817        );
818        assert_eq!(
819            <&Integer as TryInto<i64>>::try_into(
820                &Integer::from_str("9223372036854775808").unwrap()
821            ),
822            Err(())
823        );
824
825        // i128
826        assert_eq!(
827            <&Integer as TryInto<i128>>::try_into(
828                &Integer::from_str("-170141183460469231731687303715884105729").unwrap()
829            ),
830            Err(())
831        );
832        assert_eq!(
833            <&Integer as TryInto<i128>>::try_into(
834                &Integer::from_str("-170141183460469231731687303715884105728").unwrap()
835            ),
836            Ok(-170141183460469231731687303715884105728)
837        );
838        assert_eq!(
839            <&Integer as TryInto<i128>>::try_into(
840                &Integer::from_str("170141183460469231731687303715884105727").unwrap()
841            ),
842            Ok(170141183460469231731687303715884105727)
843        );
844        assert_eq!(
845            <&Integer as TryInto<i128>>::try_into(
846                &Integer::from_str("170141183460469231731687303715884105728").unwrap()
847            ),
848            Err(())
849        );
850    }
851}