1 //! Type-level signed integers.
4 //! Type **operators** implemented:
6 //! From `core::ops`: `Add`, `Sub`, `Mul`, `Div`, and `Rem`.
7 //! From `typenum`: `Same`, `Cmp`, and `Pow`.
9 //! Rather than directly using the structs defined in this module, it is recommended that
10 //! you import and use the relevant aliases from the [consts](../consts/index.html) module.
12 //! Note that operators that work on the underlying structure of the number are
13 //! intentionally not implemented. This is because this implementation of signed integers
14 //! does *not* use twos-complement, and implementing them would require making arbitrary
15 //! choices, causing the results of such operators to be difficult to reason about.
19 //! use std::ops::{Add, Div, Mul, Rem, Sub};
20 //! use typenum::{Integer, N3, P2};
22 //! assert_eq!(<N3 as Add<P2>>::Output::to_i32(), -1);
23 //! assert_eq!(<N3 as Sub<P2>>::Output::to_i32(), -5);
24 //! assert_eq!(<N3 as Mul<P2>>::Output::to_i32(), -6);
25 //! assert_eq!(<N3 as Div<P2>>::Output::to_i32(), -1);
26 //! assert_eq!(<N3 as Rem<P2>>::Output::to_i32(), -1);
29 pub use crate::marker_traits
::Integer
;
32 consts
::{N1, P1, U0, U1}
,
33 private
::{Internal, InternalMarker, PrivateDivInt, PrivateIntegerAdd, PrivateRem}
,
34 uint
::{UInt, Unsigned}
,
35 Cmp
, Equal
, Greater
, Less
, NonZero
, Pow
, PowerOfTwo
, ToInt
, Zero
,
37 use core
::ops
::{Add, Div, Mul, Neg, Rem, Sub}
;
39 /// Type-level signed integers with positive sign.
40 #[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)]
41 pub struct PInt
<U
: Unsigned
+ NonZero
> {
45 /// Type-level signed integers with negative sign.
46 #[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)]
47 pub struct NInt
<U
: Unsigned
+ NonZero
> {
51 impl<U
: Unsigned
+ NonZero
> PInt
<U
> {
52 /// Instantiates a singleton representing this strictly positive integer.
54 pub fn new() -> PInt
<U
> {
59 impl<U
: Unsigned
+ NonZero
> NInt
<U
> {
60 /// Instantiates a singleton representing this strictly negative integer.
62 pub fn new() -> NInt
<U
> {
67 /// The type-level signed integer 0.
68 #[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)]
72 /// Instantiates a singleton representing the integer 0.
79 impl<U
: Unsigned
+ NonZero
> NonZero
for PInt
<U
> {}
80 impl<U
: Unsigned
+ NonZero
> NonZero
for NInt
<U
> {}
83 impl<U
: Unsigned
+ NonZero
+ PowerOfTwo
> PowerOfTwo
for PInt
<U
> {}
90 #[cfg(feature = "i128")]
92 const ISIZE
: isize = 0;
110 #[cfg(feature = "i128")]
112 fn to_i128() -> i128
{
116 fn to_isize() -> isize {
121 impl<U
: Unsigned
+ NonZero
> Integer
for PInt
<U
> {
122 const I8
: i8 = U
::I8
;
123 const I16
: i16 = U
::I16
;
124 const I32
: i32 = U
::I32
;
125 const I64
: i64 = U
::I64
;
126 #[cfg(feature = "i128")]
127 const I128
: i128
= U
::I128
;
128 const ISIZE
: isize = U
::ISIZE
;
132 <U
as Unsigned
>::to_i8()
136 <U
as Unsigned
>::to_i16()
140 <U
as Unsigned
>::to_i32()
144 <U
as Unsigned
>::to_i64()
146 #[cfg(feature = "i128")]
148 fn to_i128() -> i128
{
149 <U
as Unsigned
>::to_i128()
152 fn to_isize() -> isize {
153 <U
as Unsigned
>::to_isize()
157 // Simply negating the result of e.g. `U::I8` will result in overflow for `std::i8::MIN`. Instead,
158 // we use the fact that `U: NonZero` by subtracting one from the `U::U8` before negating.
159 impl<U
: Unsigned
+ NonZero
> Integer
for NInt
<U
> {
160 const I8
: i8 = -((U
::U8
- 1) as i8) - 1;
161 const I16
: i16 = -((U
::U16
- 1) as i16) - 1;
162 const I32
: i32 = -((U
::U32
- 1) as i32) - 1;
163 const I64
: i64 = -((U
::U64
- 1) as i64) - 1;
164 #[cfg(feature = "i128")]
165 const I128
: i128
= -((U
::U128
- 1) as i128
) - 1;
166 const ISIZE
: isize = -((U
::USIZE
- 1) as isize) - 1;
184 #[cfg(feature = "i128")]
186 fn to_i128() -> i128
{
190 fn to_isize() -> isize {
195 // ---------------------------------------------------------------------------------------
202 fn neg(self) -> Self::Output
{
208 impl<U
: Unsigned
+ NonZero
> Neg
for PInt
<U
> {
209 type Output
= NInt
<U
>;
211 fn neg(self) -> Self::Output
{
217 impl<U
: Unsigned
+ NonZero
> Neg
for NInt
<U
> {
218 type Output
= PInt
<U
>;
220 fn neg(self) -> Self::Output
{
225 // ---------------------------------------------------------------------------------------
229 impl<I
: Integer
> Add
<I
> for Z0
{
232 fn add(self, rhs
: I
) -> Self::Output
{
237 /// `PInt + Z0 = PInt`
238 impl<U
: Unsigned
+ NonZero
> Add
<Z0
> for PInt
<U
> {
239 type Output
= PInt
<U
>;
241 fn add(self, _
: Z0
) -> Self::Output
{
246 /// `NInt + Z0 = NInt`
247 impl<U
: Unsigned
+ NonZero
> Add
<Z0
> for NInt
<U
> {
248 type Output
= NInt
<U
>;
250 fn add(self, _
: Z0
) -> Self::Output
{
255 /// `P(Ul) + P(Ur) = P(Ul + Ur)`
256 impl<Ul
: Unsigned
+ NonZero
, Ur
: Unsigned
+ NonZero
> Add
<PInt
<Ur
>> for PInt
<Ul
>
259 <Ul
as Add
<Ur
>>::Output
: Unsigned
+ NonZero
,
261 type Output
= PInt
<<Ul
as Add
<Ur
>>::Output
>;
263 fn add(self, _
: PInt
<Ur
>) -> Self::Output
{
268 /// `N(Ul) + N(Ur) = N(Ul + Ur)`
269 impl<Ul
: Unsigned
+ NonZero
, Ur
: Unsigned
+ NonZero
> Add
<NInt
<Ur
>> for NInt
<Ul
>
272 <Ul
as Add
<Ur
>>::Output
: Unsigned
+ NonZero
,
274 type Output
= NInt
<<Ul
as Add
<Ur
>>::Output
>;
276 fn add(self, _
: NInt
<Ur
>) -> Self::Output
{
281 /// `P(Ul) + N(Ur)`: We resolve this with our `PrivateAdd`
282 impl<Ul
: Unsigned
+ NonZero
, Ur
: Unsigned
+ NonZero
> Add
<NInt
<Ur
>> for PInt
<Ul
>
284 Ul
: Cmp
<Ur
> + PrivateIntegerAdd
<<Ul
as Cmp
<Ur
>>::Output
, Ur
>,
286 type Output
= <Ul
as PrivateIntegerAdd
<<Ul
as Cmp
<Ur
>>::Output
, Ur
>>::Output
;
288 fn add(self, rhs
: NInt
<Ur
>) -> Self::Output
{
291 let lhs_cmp_rhs
= lhs
.compare
::<Internal
>(&rhs
);
292 lhs
.private_integer_add(lhs_cmp_rhs
, rhs
)
296 /// `N(Ul) + P(Ur)`: We resolve this with our `PrivateAdd`
297 // We just do the same thing as above, swapping Lhs and Rhs
298 impl<Ul
: Unsigned
+ NonZero
, Ur
: Unsigned
+ NonZero
> Add
<PInt
<Ur
>> for NInt
<Ul
>
300 Ur
: Cmp
<Ul
> + PrivateIntegerAdd
<<Ur
as Cmp
<Ul
>>::Output
, Ul
>,
302 type Output
= <Ur
as PrivateIntegerAdd
<<Ur
as Cmp
<Ul
>>::Output
, Ul
>>::Output
;
304 fn add(self, rhs
: PInt
<Ur
>) -> Self::Output
{
307 let rhs_cmp_lhs
= rhs
.compare
::<Internal
>(&lhs
);
308 rhs
.private_integer_add(rhs_cmp_lhs
, lhs
)
312 /// `P + N = 0` where `P == N`
313 impl<N
: Unsigned
, P
: Unsigned
> PrivateIntegerAdd
<Equal
, N
> for P
{
317 fn private_integer_add(self, _
: Equal
, _
: N
) -> Self::Output
{
322 /// `P + N = Positive` where `P > N`
323 impl<N
: Unsigned
, P
: Unsigned
> PrivateIntegerAdd
<Greater
, N
> for P
326 <P
as Sub
<N
>>::Output
: Unsigned
+ NonZero
,
328 type Output
= PInt
<<P
as Sub
<N
>>::Output
>;
331 fn private_integer_add(self, _
: Greater
, n
: N
) -> Self::Output
{
336 /// `P + N = Negative` where `P < N`
337 impl<N
: Unsigned
, P
: Unsigned
> PrivateIntegerAdd
<Less
, N
> for P
340 <N
as Sub
<P
>>::Output
: Unsigned
+ NonZero
,
342 type Output
= NInt
<<N
as Sub
<P
>>::Output
>;
345 fn private_integer_add(self, _
: Less
, n
: N
) -> Self::Output
{
350 // ---------------------------------------------------------------------------------------
354 impl Sub
<Z0
> for Z0
{
357 fn sub(self, _
: Z0
) -> Self::Output
{
363 impl<U
: Unsigned
+ NonZero
> Sub
<PInt
<U
>> for Z0
{
364 type Output
= NInt
<U
>;
366 fn sub(self, _
: PInt
<U
>) -> Self::Output
{
372 impl<U
: Unsigned
+ NonZero
> Sub
<NInt
<U
>> for Z0
{
373 type Output
= PInt
<U
>;
375 fn sub(self, _
: NInt
<U
>) -> Self::Output
{
380 /// `PInt - Z0 = PInt`
381 impl<U
: Unsigned
+ NonZero
> Sub
<Z0
> for PInt
<U
> {
382 type Output
= PInt
<U
>;
384 fn sub(self, _
: Z0
) -> Self::Output
{
389 /// `NInt - Z0 = NInt`
390 impl<U
: Unsigned
+ NonZero
> Sub
<Z0
> for NInt
<U
> {
391 type Output
= NInt
<U
>;
393 fn sub(self, _
: Z0
) -> Self::Output
{
398 /// `P(Ul) - N(Ur) = P(Ul + Ur)`
399 impl<Ul
: Unsigned
+ NonZero
, Ur
: Unsigned
+ NonZero
> Sub
<NInt
<Ur
>> for PInt
<Ul
>
402 <Ul
as Add
<Ur
>>::Output
: Unsigned
+ NonZero
,
404 type Output
= PInt
<<Ul
as Add
<Ur
>>::Output
>;
406 fn sub(self, _
: NInt
<Ur
>) -> Self::Output
{
411 /// `N(Ul) - P(Ur) = N(Ul + Ur)`
412 impl<Ul
: Unsigned
+ NonZero
, Ur
: Unsigned
+ NonZero
> Sub
<PInt
<Ur
>> for NInt
<Ul
>
415 <Ul
as Add
<Ur
>>::Output
: Unsigned
+ NonZero
,
417 type Output
= NInt
<<Ul
as Add
<Ur
>>::Output
>;
419 fn sub(self, _
: PInt
<Ur
>) -> Self::Output
{
424 /// `P(Ul) - P(Ur)`: We resolve this with our `PrivateAdd`
425 impl<Ul
: Unsigned
+ NonZero
, Ur
: Unsigned
+ NonZero
> Sub
<PInt
<Ur
>> for PInt
<Ul
>
427 Ul
: Cmp
<Ur
> + PrivateIntegerAdd
<<Ul
as Cmp
<Ur
>>::Output
, Ur
>,
429 type Output
= <Ul
as PrivateIntegerAdd
<<Ul
as Cmp
<Ur
>>::Output
, Ur
>>::Output
;
431 fn sub(self, rhs
: PInt
<Ur
>) -> Self::Output
{
434 let lhs_cmp_rhs
= lhs
.compare
::<Internal
>(&rhs
);
435 lhs
.private_integer_add(lhs_cmp_rhs
, rhs
)
439 /// `N(Ul) - N(Ur)`: We resolve this with our `PrivateAdd`
440 // We just do the same thing as above, swapping Lhs and Rhs
441 impl<Ul
: Unsigned
+ NonZero
, Ur
: Unsigned
+ NonZero
> Sub
<NInt
<Ur
>> for NInt
<Ul
>
443 Ur
: Cmp
<Ul
> + PrivateIntegerAdd
<<Ur
as Cmp
<Ul
>>::Output
, Ul
>,
445 type Output
= <Ur
as PrivateIntegerAdd
<<Ur
as Cmp
<Ul
>>::Output
, Ul
>>::Output
;
447 fn sub(self, rhs
: NInt
<Ur
>) -> Self::Output
{
450 let rhs_cmp_lhs
= rhs
.compare
::<Internal
>(&lhs
);
451 rhs
.private_integer_add(rhs_cmp_lhs
, lhs
)
455 // ---------------------------------------------------------------------------------------
459 impl<I
: Integer
> Mul
<I
> for Z0
{
462 fn mul(self, _
: I
) -> Self::Output
{
468 impl<U
: Unsigned
+ NonZero
> Mul
<Z0
> for PInt
<U
> {
471 fn mul(self, _
: Z0
) -> Self::Output
{
477 impl<U
: Unsigned
+ NonZero
> Mul
<Z0
> for NInt
<U
> {
480 fn mul(self, _
: Z0
) -> Self::Output
{
485 /// P(Ul) * P(Ur) = P(Ul * Ur)
486 impl<Ul
: Unsigned
+ NonZero
, Ur
: Unsigned
+ NonZero
> Mul
<PInt
<Ur
>> for PInt
<Ul
>
489 <Ul
as Mul
<Ur
>>::Output
: Unsigned
+ NonZero
,
491 type Output
= PInt
<<Ul
as Mul
<Ur
>>::Output
>;
493 fn mul(self, _
: PInt
<Ur
>) -> Self::Output
{
498 /// N(Ul) * N(Ur) = P(Ul * Ur)
499 impl<Ul
: Unsigned
+ NonZero
, Ur
: Unsigned
+ NonZero
> Mul
<NInt
<Ur
>> for NInt
<Ul
>
502 <Ul
as Mul
<Ur
>>::Output
: Unsigned
+ NonZero
,
504 type Output
= PInt
<<Ul
as Mul
<Ur
>>::Output
>;
506 fn mul(self, _
: NInt
<Ur
>) -> Self::Output
{
511 /// P(Ul) * N(Ur) = N(Ul * Ur)
512 impl<Ul
: Unsigned
+ NonZero
, Ur
: Unsigned
+ NonZero
> Mul
<NInt
<Ur
>> for PInt
<Ul
>
515 <Ul
as Mul
<Ur
>>::Output
: Unsigned
+ NonZero
,
517 type Output
= NInt
<<Ul
as Mul
<Ur
>>::Output
>;
519 fn mul(self, _
: NInt
<Ur
>) -> Self::Output
{
524 /// N(Ul) * P(Ur) = N(Ul * Ur)
525 impl<Ul
: Unsigned
+ NonZero
, Ur
: Unsigned
+ NonZero
> Mul
<PInt
<Ur
>> for NInt
<Ul
>
528 <Ul
as Mul
<Ur
>>::Output
: Unsigned
+ NonZero
,
530 type Output
= NInt
<<Ul
as Mul
<Ur
>>::Output
>;
532 fn mul(self, _
: PInt
<Ur
>) -> Self::Output
{
537 // ---------------------------------------------------------------------------------------
540 /// `Z0 / I = Z0` where `I != 0`
541 impl<I
: Integer
+ NonZero
> Div
<I
> for Z0
{
544 fn div(self, _
: I
) -> Self::Output
{
549 macro_rules
! impl_int_div
{
550 ($A
:ident
, $B
:ident
, $R
:ident
) => {
551 /// `$A<Ul> / $B<Ur> = $R<Ul / Ur>`
552 impl<Ul
: Unsigned
+ NonZero
, Ur
: Unsigned
+ NonZero
> Div
<$B
<Ur
>> for $A
<Ul
>
555 $A
<Ul
>: PrivateDivInt
<<Ul
as Cmp
<Ur
>>::Output
, $B
<Ur
>>,
557 type Output
= <$A
<Ul
> as PrivateDivInt
<<Ul
as Cmp
<Ur
>>::Output
, $B
<Ur
>>>::Output
;
559 fn div(self, rhs
: $B
<Ur
>) -> Self::Output
{
560 let lhs_cmp_rhs
= self.n
.compare
::<Internal
>(&rhs
.n
);
561 self.private_div_int(lhs_cmp_rhs
, rhs
)
564 impl<Ul
, Ur
> PrivateDivInt
<Less
, $B
<Ur
>> for $A
<Ul
>
566 Ul
: Unsigned
+ NonZero
,
567 Ur
: Unsigned
+ NonZero
,
572 fn private_div_int(self, _
: Less
, _
: $B
<Ur
>) -> Self::Output
{
576 impl<Ul
, Ur
> PrivateDivInt
<Equal
, $B
<Ur
>> for $A
<Ul
>
578 Ul
: Unsigned
+ NonZero
,
579 Ur
: Unsigned
+ NonZero
,
581 type Output
= $R
<U1
>;
584 fn private_div_int(self, _
: Equal
, _
: $B
<Ur
>) -> Self::Output
{
588 impl<Ul
, Ur
> PrivateDivInt
<Greater
, $B
<Ur
>> for $A
<Ul
>
590 Ul
: Unsigned
+ NonZero
+ Div
<Ur
>,
591 Ur
: Unsigned
+ NonZero
,
592 <Ul
as Div
<Ur
>>::Output
: Unsigned
+ NonZero
,
594 type Output
= $R
<<Ul
as Div
<Ur
>>::Output
>;
597 fn private_div_int(self, _
: Greater
, d
: $B
<Ur
>) -> Self::Output
{
598 $R { n: self.n / d.n }
604 impl_int_div
!(PInt
, PInt
, PInt
);
605 impl_int_div
!(PInt
, NInt
, NInt
);
606 impl_int_div
!(NInt
, PInt
, NInt
);
607 impl_int_div
!(NInt
, NInt
, PInt
);
609 // ---------------------------------------------------------------------------------------
612 use crate::{PartialDiv, Quot}
;
614 impl<M
, N
> PartialDiv
<N
> for M
616 M
: Integer
+ Div
<N
> + Rem
<N
, Output
= Z0
>,
618 type Output
= Quot
<M
, N
>;
620 fn partial_div(self, rhs
: N
) -> Self::Output
{
625 // ---------------------------------------------------------------------------------------
629 impl Cmp
<Z0
> for Z0
{
633 fn compare
<IM
: InternalMarker
>(&self, _
: &Z0
) -> Self::Output
{
639 impl<U
: Unsigned
+ NonZero
> Cmp
<NInt
<U
>> for Z0
{
640 type Output
= Greater
;
643 fn compare
<IM
: InternalMarker
>(&self, _
: &NInt
<U
>) -> Self::Output
{
649 impl<U
: Unsigned
+ NonZero
> Cmp
<PInt
<U
>> for Z0
{
653 fn compare
<IM
: InternalMarker
>(&self, _
: &PInt
<U
>) -> Self::Output
{
659 impl<U
: Unsigned
+ NonZero
> Cmp
<Z0
> for PInt
<U
> {
660 type Output
= Greater
;
663 fn compare
<IM
: InternalMarker
>(&self, _
: &Z0
) -> Self::Output
{
669 impl<U
: Unsigned
+ NonZero
> Cmp
<Z0
> for NInt
<U
> {
673 fn compare
<IM
: InternalMarker
>(&self, _
: &Z0
) -> Self::Output
{
679 impl<P
: Unsigned
+ NonZero
, N
: Unsigned
+ NonZero
> Cmp
<PInt
<P
>> for NInt
<N
> {
683 fn compare
<IM
: InternalMarker
>(&self, _
: &PInt
<P
>) -> Self::Output
{
689 impl<P
: Unsigned
+ NonZero
, N
: Unsigned
+ NonZero
> Cmp
<NInt
<N
>> for PInt
<P
> {
690 type Output
= Greater
;
693 fn compare
<IM
: InternalMarker
>(&self, _
: &NInt
<N
>) -> Self::Output
{
699 impl<Pl
: Cmp
<Pr
> + Unsigned
+ NonZero
, Pr
: Unsigned
+ NonZero
> Cmp
<PInt
<Pr
>> for PInt
<Pl
> {
700 type Output
= <Pl
as Cmp
<Pr
>>::Output
;
703 fn compare
<IM
: InternalMarker
>(&self, rhs
: &PInt
<Pr
>) -> Self::Output
{
704 self.n
.compare
::<Internal
>(&rhs
.n
)
709 impl<Nl
: Unsigned
+ NonZero
, Nr
: Cmp
<Nl
> + Unsigned
+ NonZero
> Cmp
<NInt
<Nr
>> for NInt
<Nl
> {
710 type Output
= <Nr
as Cmp
<Nl
>>::Output
;
713 fn compare
<IM
: InternalMarker
>(&self, rhs
: &NInt
<Nr
>) -> Self::Output
{
714 rhs
.n
.compare
::<Internal
>(&self.n
)
718 // ---------------------------------------------------------------------------------------
721 /// `Z0 % I = Z0` where `I != 0`
722 impl<I
: Integer
+ NonZero
> Rem
<I
> for Z0
{
725 fn rem(self, _
: I
) -> Self::Output
{
730 macro_rules
! impl_int_rem
{
731 ($A
:ident
, $B
:ident
, $R
:ident
) => {
732 /// `$A<Ul> % $B<Ur> = $R<Ul % Ur>`
733 impl<Ul
: Unsigned
+ NonZero
, Ur
: Unsigned
+ NonZero
> Rem
<$B
<Ur
>> for $A
<Ul
>
736 $A
<Ul
>: PrivateRem
<<Ul
as Rem
<Ur
>>::Output
, $B
<Ur
>>,
738 type Output
= <$A
<Ul
> as PrivateRem
<<Ul
as Rem
<Ur
>>::Output
, $B
<Ur
>>>::Output
;
740 fn rem(self, rhs
: $B
<Ur
>) -> Self::Output
{
741 self.private_rem(self.n
% rhs
.n
, rhs
)
744 impl<Ul
: Unsigned
+ NonZero
, Ur
: Unsigned
+ NonZero
> PrivateRem
<U0
, $B
<Ur
>> for $A
<Ul
> {
748 fn private_rem(self, _
: U0
, _
: $B
<Ur
>) -> Self::Output
{
752 impl<Ul
, Ur
, U
, B
> PrivateRem
<UInt
<U
, B
>, $B
<Ur
>> for $A
<Ul
>
754 Ul
: Unsigned
+ NonZero
,
755 Ur
: Unsigned
+ NonZero
,
759 type Output
= $R
<UInt
<U
, B
>>;
762 fn private_rem(self, urem
: UInt
<U
, B
>, _
: $B
<Ur
>) -> Self::Output
{
769 impl_int_rem
!(PInt
, PInt
, PInt
);
770 impl_int_rem
!(PInt
, NInt
, PInt
);
771 impl_int_rem
!(NInt
, PInt
, NInt
);
772 impl_int_rem
!(NInt
, NInt
, NInt
);
774 // ---------------------------------------------------------------------------------------
778 impl Pow
<Z0
> for Z0
{
781 fn powi(self, _
: Z0
) -> Self::Output
{
787 impl<U
: Unsigned
+ NonZero
> Pow
<PInt
<U
>> for Z0
{
790 fn powi(self, _
: PInt
<U
>) -> Self::Output
{
796 impl<U
: Unsigned
+ NonZero
> Pow
<NInt
<U
>> for Z0
{
799 fn powi(self, _
: NInt
<U
>) -> Self::Output
{
805 impl<U
: Unsigned
+ NonZero
> Pow
<NInt
<U
>> for P1
{
808 fn powi(self, _
: NInt
<U
>) -> Self::Output
{
813 /// (-1)^N = 1 if N is even
814 impl<U
: Unsigned
> Pow
<NInt
<UInt
<U
, B0
>>> for N1
{
817 fn powi(self, _
: NInt
<UInt
<U
, B0
>>) -> Self::Output
{
822 /// (-1)^N = -1 if N is odd
823 impl<U
: Unsigned
> Pow
<NInt
<UInt
<U
, B1
>>> for N1
{
826 fn powi(self, _
: NInt
<UInt
<U
, B1
>>) -> Self::Output
{
832 impl<U
: Unsigned
+ NonZero
> Pow
<Z0
> for PInt
<U
> {
835 fn powi(self, _
: Z0
) -> Self::Output
{
841 impl<U
: Unsigned
+ NonZero
> Pow
<Z0
> for NInt
<U
> {
844 fn powi(self, _
: Z0
) -> Self::Output
{
849 /// P(Ul)^P(Ur) = P(Ul^Ur)
850 impl<Ul
: Unsigned
+ NonZero
, Ur
: Unsigned
+ NonZero
> Pow
<PInt
<Ur
>> for PInt
<Ul
>
853 <Ul
as Pow
<Ur
>>::Output
: Unsigned
+ NonZero
,
855 type Output
= PInt
<<Ul
as Pow
<Ur
>>::Output
>;
857 fn powi(self, _
: PInt
<Ur
>) -> Self::Output
{
862 /// N(Ul)^P(Ur) = P(Ul^Ur) if Ur is even
863 impl<Ul
: Unsigned
+ NonZero
, Ur
: Unsigned
> Pow
<PInt
<UInt
<Ur
, B0
>>> for NInt
<Ul
>
865 Ul
: Pow
<UInt
<Ur
, B0
>>,
866 <Ul
as Pow
<UInt
<Ur
, B0
>>>::Output
: Unsigned
+ NonZero
,
868 type Output
= PInt
<<Ul
as Pow
<UInt
<Ur
, B0
>>>::Output
>;
870 fn powi(self, _
: PInt
<UInt
<Ur
, B0
>>) -> Self::Output
{
875 /// N(Ul)^P(Ur) = N(Ul^Ur) if Ur is odd
876 impl<Ul
: Unsigned
+ NonZero
, Ur
: Unsigned
> Pow
<PInt
<UInt
<Ur
, B1
>>> for NInt
<Ul
>
878 Ul
: Pow
<UInt
<Ur
, B1
>>,
879 <Ul
as Pow
<UInt
<Ur
, B1
>>>::Output
: Unsigned
+ NonZero
,
881 type Output
= NInt
<<Ul
as Pow
<UInt
<Ur
, B1
>>>::Output
>;
883 fn powi(self, _
: PInt
<UInt
<Ur
, B1
>>) -> Self::Output
{
888 // ---------------------------------------------------------------------------------------
890 use crate::{Gcd, Gcf}
;
892 impl Gcd
<Z0
> for Z0
{
896 impl<U
> Gcd
<PInt
<U
>> for Z0
898 U
: Unsigned
+ NonZero
,
900 type Output
= PInt
<U
>;
903 impl<U
> Gcd
<Z0
> for PInt
<U
>
905 U
: Unsigned
+ NonZero
,
907 type Output
= PInt
<U
>;
910 impl<U
> Gcd
<NInt
<U
>> for Z0
912 U
: Unsigned
+ NonZero
,
914 type Output
= PInt
<U
>;
917 impl<U
> Gcd
<Z0
> for NInt
<U
>
919 U
: Unsigned
+ NonZero
,
921 type Output
= PInt
<U
>;
924 impl<U1
, U2
> Gcd
<PInt
<U2
>> for PInt
<U1
>
926 U1
: Unsigned
+ NonZero
+ Gcd
<U2
>,
927 U2
: Unsigned
+ NonZero
,
928 Gcf
<U1
, U2
>: Unsigned
+ NonZero
,
930 type Output
= PInt
<Gcf
<U1
, U2
>>;
933 impl<U1
, U2
> Gcd
<PInt
<U2
>> for NInt
<U1
>
935 U1
: Unsigned
+ NonZero
+ Gcd
<U2
>,
936 U2
: Unsigned
+ NonZero
,
937 Gcf
<U1
, U2
>: Unsigned
+ NonZero
,
939 type Output
= PInt
<Gcf
<U1
, U2
>>;
942 impl<U1
, U2
> Gcd
<NInt
<U2
>> for PInt
<U1
>
944 U1
: Unsigned
+ NonZero
+ Gcd
<U2
>,
945 U2
: Unsigned
+ NonZero
,
946 Gcf
<U1
, U2
>: Unsigned
+ NonZero
,
948 type Output
= PInt
<Gcf
<U1
, U2
>>;
951 impl<U1
, U2
> Gcd
<NInt
<U2
>> for NInt
<U1
>
953 U1
: Unsigned
+ NonZero
+ Gcd
<U2
>,
954 U2
: Unsigned
+ NonZero
,
955 Gcf
<U1
, U2
>: Unsigned
+ NonZero
,
957 type Output
= PInt
<Gcf
<U1
, U2
>>;
960 // ---------------------------------------------------------------------------------------
962 use crate::{Max, Maximum, Min, Minimum}
;
964 impl Min
<Z0
> for Z0
{
967 fn min(self, _
: Z0
) -> Self::Output
{
972 impl<U
> Min
<PInt
<U
>> for Z0
974 U
: Unsigned
+ NonZero
,
978 fn min(self, _
: PInt
<U
>) -> Self::Output
{
983 impl<U
> Min
<NInt
<U
>> for Z0
985 U
: Unsigned
+ NonZero
,
987 type Output
= NInt
<U
>;
989 fn min(self, rhs
: NInt
<U
>) -> Self::Output
{
994 impl<U
> Min
<Z0
> for PInt
<U
>
996 U
: Unsigned
+ NonZero
,
1000 fn min(self, rhs
: Z0
) -> Self::Output
{
1005 impl<U
> Min
<Z0
> for NInt
<U
>
1007 U
: Unsigned
+ NonZero
,
1009 type Output
= NInt
<U
>;
1011 fn min(self, _
: Z0
) -> Self::Output
{
1016 impl<Ul
, Ur
> Min
<PInt
<Ur
>> for PInt
<Ul
>
1018 Ul
: Unsigned
+ NonZero
+ Min
<Ur
>,
1019 Ur
: Unsigned
+ NonZero
,
1020 Minimum
<Ul
, Ur
>: Unsigned
+ NonZero
,
1022 type Output
= PInt
<Minimum
<Ul
, Ur
>>;
1024 fn min(self, rhs
: PInt
<Ur
>) -> Self::Output
{
1026 n
: self.n
.min(rhs
.n
),
1031 impl<Ul
, Ur
> Min
<PInt
<Ur
>> for NInt
<Ul
>
1033 Ul
: Unsigned
+ NonZero
,
1034 Ur
: Unsigned
+ NonZero
,
1036 type Output
= NInt
<Ul
>;
1038 fn min(self, _
: PInt
<Ur
>) -> Self::Output
{
1043 impl<Ul
, Ur
> Min
<NInt
<Ur
>> for PInt
<Ul
>
1045 Ul
: Unsigned
+ NonZero
,
1046 Ur
: Unsigned
+ NonZero
,
1048 type Output
= NInt
<Ur
>;
1050 fn min(self, rhs
: NInt
<Ur
>) -> Self::Output
{
1055 impl<Ul
, Ur
> Min
<NInt
<Ur
>> for NInt
<Ul
>
1057 Ul
: Unsigned
+ NonZero
+ Max
<Ur
>,
1058 Ur
: Unsigned
+ NonZero
,
1059 Maximum
<Ul
, Ur
>: Unsigned
+ NonZero
,
1061 type Output
= NInt
<Maximum
<Ul
, Ur
>>;
1063 fn min(self, rhs
: NInt
<Ur
>) -> Self::Output
{
1065 n
: self.n
.max(rhs
.n
),
1070 // ---------------------------------------------------------------------------------------
1073 impl Max
<Z0
> for Z0
{
1076 fn max(self, _
: Z0
) -> Self::Output
{
1081 impl<U
> Max
<PInt
<U
>> for Z0
1083 U
: Unsigned
+ NonZero
,
1085 type Output
= PInt
<U
>;
1087 fn max(self, rhs
: PInt
<U
>) -> Self::Output
{
1092 impl<U
> Max
<NInt
<U
>> for Z0
1094 U
: Unsigned
+ NonZero
,
1098 fn max(self, _
: NInt
<U
>) -> Self::Output
{
1103 impl<U
> Max
<Z0
> for PInt
<U
>
1105 U
: Unsigned
+ NonZero
,
1107 type Output
= PInt
<U
>;
1109 fn max(self, _
: Z0
) -> Self::Output
{
1114 impl<U
> Max
<Z0
> for NInt
<U
>
1116 U
: Unsigned
+ NonZero
,
1120 fn max(self, rhs
: Z0
) -> Self::Output
{
1125 impl<Ul
, Ur
> Max
<PInt
<Ur
>> for PInt
<Ul
>
1127 Ul
: Unsigned
+ NonZero
+ Max
<Ur
>,
1128 Ur
: Unsigned
+ NonZero
,
1129 Maximum
<Ul
, Ur
>: Unsigned
+ NonZero
,
1131 type Output
= PInt
<Maximum
<Ul
, Ur
>>;
1133 fn max(self, rhs
: PInt
<Ur
>) -> Self::Output
{
1135 n
: self.n
.max(rhs
.n
),
1140 impl<Ul
, Ur
> Max
<PInt
<Ur
>> for NInt
<Ul
>
1142 Ul
: Unsigned
+ NonZero
,
1143 Ur
: Unsigned
+ NonZero
,
1145 type Output
= PInt
<Ur
>;
1147 fn max(self, rhs
: PInt
<Ur
>) -> Self::Output
{
1152 impl<Ul
, Ur
> Max
<NInt
<Ur
>> for PInt
<Ul
>
1154 Ul
: Unsigned
+ NonZero
,
1155 Ur
: Unsigned
+ NonZero
,
1157 type Output
= PInt
<Ul
>;
1159 fn max(self, _
: NInt
<Ur
>) -> Self::Output
{
1164 impl<Ul
, Ur
> Max
<NInt
<Ur
>> for NInt
<Ul
>
1166 Ul
: Unsigned
+ NonZero
+ Min
<Ur
>,
1167 Ur
: Unsigned
+ NonZero
,
1168 Minimum
<Ul
, Ur
>: Unsigned
+ NonZero
,
1170 type Output
= NInt
<Minimum
<Ul
, Ur
>>;
1172 fn max(self, rhs
: NInt
<Ur
>) -> Self::Output
{
1174 n
: self.n
.min(rhs
.n
),
1179 // -----------------------------------------
1182 impl ToInt
<i8> for Z0
{
1189 impl ToInt
<i16> for Z0
{
1191 fn to_int() -> i16 {
1196 impl ToInt
<i32> for Z0
{
1198 fn to_int() -> i32 {
1203 impl ToInt
<i64> for Z0
{
1205 fn to_int() -> i64 {
1212 impl<U
> ToInt
<i8> for NInt
<U
>
1214 U
: Unsigned
+ NonZero
,
1222 impl<U
> ToInt
<i16> for NInt
<U
>
1224 U
: Unsigned
+ NonZero
,
1227 fn to_int() -> i16 {
1232 impl<U
> ToInt
<i32> for NInt
<U
>
1234 U
: Unsigned
+ NonZero
,
1237 fn to_int() -> i32 {
1242 impl<U
> ToInt
<i64> for NInt
<U
>
1244 U
: Unsigned
+ NonZero
,
1247 fn to_int() -> i64 {
1254 impl<U
> ToInt
<i8> for PInt
<U
>
1256 U
: Unsigned
+ NonZero
,
1264 impl<U
> ToInt
<i16> for PInt
<U
>
1266 U
: Unsigned
+ NonZero
,
1269 fn to_int() -> i16 {
1274 impl<U
> ToInt
<i32> for PInt
<U
>
1276 U
: Unsigned
+ NonZero
,
1279 fn to_int() -> i32 {
1284 impl<U
> ToInt
<i64> for PInt
<U
>
1286 U
: Unsigned
+ NonZero
,
1289 fn to_int() -> i64 {
1296 use crate::{consts::*, Integer, ToInt}
;
1300 assert_eq
!(N128
::to_i8(), ::core
::i8::MIN
);
1301 assert_eq
!(N32768
::to_i16(), ::core
::i16::MIN
);
1305 fn int_toint_test() {
1307 assert_eq
!(0_i8, Z0
::to_int());
1308 assert_eq
!(1_i8, P1
::to_int());
1309 assert_eq
!(2_i8, P2
::to_int());
1310 assert_eq
!(3_i8, P3
::to_int());
1311 assert_eq
!(4_i8, P4
::to_int());
1312 assert_eq
!(-1_i8, N1
::to_int());
1313 assert_eq
!(-2_i8, N2
::to_int());
1314 assert_eq
!(-3_i8, N3
::to_int());
1315 assert_eq
!(-4_i8, N4
::to_int());
1318 assert_eq
!(0_i16, Z0
::to_int());
1319 assert_eq
!(1_i16, P1
::to_int());
1320 assert_eq
!(2_i16, P2
::to_int());
1321 assert_eq
!(3_i16, P3
::to_int());
1322 assert_eq
!(4_i16, P4
::to_int());
1323 assert_eq
!(-1_i16, N1
::to_int());
1324 assert_eq
!(-2_i16, N2
::to_int());
1325 assert_eq
!(-3_i16, N3
::to_int());
1326 assert_eq
!(-4_i16, N4
::to_int());
1329 assert_eq
!(0_i32, Z0
::to_int());
1330 assert_eq
!(1_i32, P1
::to_int());
1331 assert_eq
!(2_i32, P2
::to_int());
1332 assert_eq
!(3_i32, P3
::to_int());
1333 assert_eq
!(4_i32, P4
::to_int());
1334 assert_eq
!(-1_i32, N1
::to_int());
1335 assert_eq
!(-2_i32, N2
::to_int());
1336 assert_eq
!(-3_i32, N3
::to_int());
1337 assert_eq
!(-4_i32, N4
::to_int());
1340 assert_eq
!(0_i64, Z0
::to_int());
1341 assert_eq
!(1_i64, P1
::to_int());
1342 assert_eq
!(2_i64, P2
::to_int());
1343 assert_eq
!(3_i64, P3
::to_int());
1344 assert_eq
!(4_i64, P4
::to_int());
1345 assert_eq
!(-1_i64, N1
::to_int());
1346 assert_eq
!(-2_i64, N2
::to_int());
1347 assert_eq
!(-3_i64, N3
::to_int());
1348 assert_eq
!(-4_i64, N4
::to_int());