1use alloc::string::{String, ToString};
2use core::fmt;
3use core::ops::{
4 Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Not, Rem, RemAssign, Shl, ShlAssign, Shr,
5 ShrAssign, Sub, SubAssign,
6};
7use core::str::FromStr;
8
9use crate::errors::{
10 DivideByZeroError, DivisionError, ErrorKind, OverflowError, OverflowOperation, StdError,
11};
12use crate::forward_ref::{forward_ref_binop, forward_ref_op_assign};
13use crate::{
14 CheckedMultiplyRatioError, Int256, Int512, Int64, Uint128, Uint256, Uint512, Uint64,
15 __internal::forward_ref_partial_eq,
16};
17
18use super::conversion::{
19 forward_try_from, from_and_to_bytes, primitive_to_wrapped_int, try_from_int_to_int,
20 wrapped_int_to_primitive,
21};
22use super::impl_int_serde;
23use super::num_consts::NumConsts;
24
25#[derive(
39 Copy,
40 Clone,
41 Default,
42 Debug,
43 PartialEq,
44 Eq,
45 PartialOrd,
46 Ord,
47 schemars::JsonSchema,
48 cw_schema::Schemaifier,
49)]
50#[schemaifier(type = cw_schema::NodeType::Integer { precision: 128, signed: true })]
51pub struct Int128(#[schemars(with = "String")] pub(crate) i128);
52
53impl_int_serde!(Int128);
54forward_ref_partial_eq!(Int128, Int128);
55
56impl Int128 {
57 pub const MAX: Int128 = Int128(i128::MAX);
58 pub const MIN: Int128 = Int128(i128::MIN);
59
60 #[inline]
64 #[must_use]
65 pub const fn new(value: i128) -> Self {
66 Self(value)
67 }
68
69 #[inline]
71 pub const fn zero() -> Self {
72 Int128(0)
73 }
74
75 #[inline]
77 pub const fn one() -> Self {
78 Self(1)
79 }
80
81 pub const fn i128(&self) -> i128 {
83 self.0
84 }
85
86 from_and_to_bytes!(i128, 16);
87
88 #[must_use]
89 pub const fn is_zero(&self) -> bool {
90 self.0 == 0
91 }
92
93 #[must_use]
94 pub const fn is_negative(&self) -> bool {
95 self.0.is_negative()
96 }
97
98 #[must_use = "this returns the result of the operation, without modifying the original"]
99 pub const fn pow(self, exp: u32) -> Self {
100 match self.0.checked_pow(exp) {
101 Some(val) => Self(val),
102 None => panic!("attempt to exponentiate with overflow"),
103 }
104 }
105
106 pub fn checked_multiply_ratio<A: Into<Self>, B: Into<Self>>(
111 &self,
112 numerator: A,
113 denominator: B,
114 ) -> Result<Self, CheckedMultiplyRatioError> {
115 let numerator = numerator.into();
116 let denominator = denominator.into();
117 if denominator.is_zero() {
118 return Err(CheckedMultiplyRatioError::DivideByZero);
119 }
120 match (self.full_mul(numerator) / Int256::from(denominator)).try_into() {
121 Ok(ratio) => Ok(ratio),
122 Err(_) => Err(CheckedMultiplyRatioError::Overflow),
123 }
124 }
125
126 #[must_use = "this returns the result of the operation, without modifying the original"]
139 pub fn full_mul(self, rhs: impl Into<Self>) -> Int256 {
140 Int256::from(self)
141 .checked_mul(Int256::from(rhs.into()))
142 .unwrap()
143 }
144
145 pub fn checked_add(self, other: Self) -> Result<Self, OverflowError> {
146 self.0
147 .checked_add(other.0)
148 .map(Self)
149 .ok_or_else(|| OverflowError::new(OverflowOperation::Add))
150 }
151
152 pub fn checked_sub(self, other: Self) -> Result<Self, OverflowError> {
153 self.0
154 .checked_sub(other.0)
155 .map(Self)
156 .ok_or_else(|| OverflowError::new(OverflowOperation::Sub))
157 }
158
159 pub fn checked_mul(self, other: Self) -> Result<Self, OverflowError> {
160 self.0
161 .checked_mul(other.0)
162 .map(Self)
163 .ok_or_else(|| OverflowError::new(OverflowOperation::Mul))
164 }
165
166 pub fn checked_pow(self, exp: u32) -> Result<Self, OverflowError> {
167 self.0
168 .checked_pow(exp)
169 .map(Self)
170 .ok_or_else(|| OverflowError::new(OverflowOperation::Pow))
171 }
172
173 pub fn checked_div(self, other: Self) -> Result<Self, DivisionError> {
174 if other.is_zero() {
175 return Err(DivisionError::DivideByZero);
176 }
177 self.0
178 .checked_div(other.0)
179 .map(Self)
180 .ok_or(DivisionError::Overflow)
181 }
182
183 pub fn checked_div_euclid(self, other: Self) -> Result<Self, DivisionError> {
184 if other.is_zero() {
185 return Err(DivisionError::DivideByZero);
186 }
187 self.0
188 .checked_div_euclid(other.0)
189 .map(Self)
190 .ok_or(DivisionError::Overflow)
191 }
192
193 pub fn checked_rem(self, other: Self) -> Result<Self, DivideByZeroError> {
194 self.0
195 .checked_rem(other.0)
196 .map(Self)
197 .ok_or(DivideByZeroError)
198 }
199
200 pub fn checked_shr(self, other: u32) -> Result<Self, OverflowError> {
201 if other >= 128 {
202 return Err(OverflowError::new(OverflowOperation::Shr));
203 }
204
205 Ok(Self(self.0.shr(other)))
206 }
207
208 pub fn checked_shl(self, other: u32) -> Result<Self, OverflowError> {
209 if other >= 128 {
210 return Err(OverflowError::new(OverflowOperation::Shl));
211 }
212
213 Ok(Self(self.0.shl(other)))
214 }
215
216 #[must_use = "this returns the result of the operation, without modifying the original"]
217 #[inline]
218 pub fn wrapping_add(self, other: Self) -> Self {
219 Self(self.0.wrapping_add(other.0))
220 }
221
222 #[must_use = "this returns the result of the operation, without modifying the original"]
223 #[inline]
224 pub fn wrapping_sub(self, other: Self) -> Self {
225 Self(self.0.wrapping_sub(other.0))
226 }
227
228 #[must_use = "this returns the result of the operation, without modifying the original"]
229 #[inline]
230 pub fn wrapping_mul(self, other: Self) -> Self {
231 Self(self.0.wrapping_mul(other.0))
232 }
233
234 #[must_use = "this returns the result of the operation, without modifying the original"]
235 #[inline]
236 pub fn wrapping_pow(self, other: u32) -> Self {
237 Self(self.0.wrapping_pow(other))
238 }
239
240 #[must_use = "this returns the result of the operation, without modifying the original"]
241 pub fn saturating_add(self, other: Self) -> Self {
242 Self(self.0.saturating_add(other.0))
243 }
244
245 #[must_use = "this returns the result of the operation, without modifying the original"]
246 pub fn saturating_sub(self, other: Self) -> Self {
247 Self(self.0.saturating_sub(other.0))
248 }
249
250 #[must_use = "this returns the result of the operation, without modifying the original"]
251 pub fn saturating_mul(self, other: Self) -> Self {
252 Self(self.0.saturating_mul(other.0))
253 }
254
255 #[must_use = "this returns the result of the operation, without modifying the original"]
256 pub fn saturating_pow(self, exp: u32) -> Self {
257 Self(self.0.saturating_pow(exp))
258 }
259
260 #[must_use = "this returns the result of the operation, without modifying the original"]
261 pub const fn abs_diff(self, other: Self) -> Uint128 {
262 Uint128(self.0.abs_diff(other.0))
263 }
264
265 #[must_use = "this returns the result of the operation, without modifying the original"]
266 pub const fn abs(self) -> Self {
267 match self.0.checked_abs() {
268 Some(val) => Self(val),
269 None => panic!("attempt to calculate absolute value with overflow"),
270 }
271 }
272
273 #[must_use = "this returns the result of the operation, without modifying the original"]
274 pub const fn unsigned_abs(self) -> Uint128 {
275 Uint128(self.0.unsigned_abs())
276 }
277
278 pub const fn strict_neg(self) -> Self {
282 match self.0.checked_neg() {
283 Some(val) => Self(val),
284 None => panic!("attempt to negate with overflow"),
285 }
286 }
287}
288
289impl NumConsts for Int128 {
290 const ZERO: Self = Self::zero();
291 const ONE: Self = Self::one();
292 const MAX: Self = Self::MAX;
293 const MIN: Self = Self::MIN;
294}
295
296impl From<Uint64> for Int128 {
298 fn from(val: Uint64) -> Self {
299 val.u64().into()
300 }
301}
302forward_try_from!(Uint128, Int128);
303forward_try_from!(Uint256, Int128);
304forward_try_from!(Uint512, Int128);
305
306primitive_to_wrapped_int!(u8, Int128);
308primitive_to_wrapped_int!(u16, Int128);
309primitive_to_wrapped_int!(u32, Int128);
310primitive_to_wrapped_int!(u64, Int128);
311
312impl From<Int64> for Int128 {
314 fn from(val: Int64) -> Self {
315 val.i64().into()
316 }
317}
318
319try_from_int_to_int!(Int256, Int128);
320try_from_int_to_int!(Int512, Int128);
321
322primitive_to_wrapped_int!(i8, Int128);
324primitive_to_wrapped_int!(i16, Int128);
325primitive_to_wrapped_int!(i32, Int128);
326primitive_to_wrapped_int!(i64, Int128);
327primitive_to_wrapped_int!(i128, Int128);
328
329wrapped_int_to_primitive!(Int128, i128);
331
332impl TryFrom<&str> for Int128 {
333 type Error = StdError;
334
335 fn try_from(val: &str) -> Result<Self, Self::Error> {
336 Self::from_str(val)
337 }
338}
339
340impl FromStr for Int128 {
341 type Err = StdError;
342
343 fn from_str(s: &str) -> Result<Self, Self::Err> {
344 match s.parse::<i128>() {
345 Ok(u) => Ok(Self(u)),
346 Err(e) => {
347 Err(StdError::msg(format_args!("Parsing Int128: {e}"))
348 .with_kind(ErrorKind::Parsing))
349 }
350 }
351 }
352}
353
354impl From<Int128> for String {
355 fn from(original: Int128) -> Self {
356 original.to_string()
357 }
358}
359
360impl fmt::Display for Int128 {
361 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
362 self.0.fmt(f)
363 }
364}
365
366impl Add<Int128> for Int128 {
367 type Output = Self;
368
369 fn add(self, rhs: Self) -> Self {
370 Int128(self.0.checked_add(rhs.0).unwrap())
371 }
372}
373forward_ref_binop!(impl Add, add for Int128, Int128);
374
375impl Sub<Int128> for Int128 {
376 type Output = Self;
377
378 fn sub(self, rhs: Self) -> Self {
379 Int128(self.0.checked_sub(rhs.0).unwrap())
380 }
381}
382forward_ref_binop!(impl Sub, sub for Int128, Int128);
383
384impl SubAssign<Int128> for Int128 {
385 fn sub_assign(&mut self, rhs: Int128) {
386 self.0 = self.0.checked_sub(rhs.0).unwrap();
387 }
388}
389forward_ref_op_assign!(impl SubAssign, sub_assign for Int128, Int128);
390
391impl Div<Int128> for Int128 {
392 type Output = Self;
393
394 fn div(self, rhs: Self) -> Self::Output {
395 Self(self.0.checked_div(rhs.0).unwrap())
396 }
397}
398forward_ref_binop!(impl Div, div for Int128, Int128);
399
400impl Rem for Int128 {
401 type Output = Self;
402
403 #[inline]
407 fn rem(self, rhs: Self) -> Self {
408 Self(self.0.rem(rhs.0))
409 }
410}
411forward_ref_binop!(impl Rem, rem for Int128, Int128);
412
413impl Not for Int128 {
414 type Output = Self;
415
416 fn not(self) -> Self::Output {
417 Self(!self.0)
418 }
419}
420
421impl Neg for Int128 {
422 type Output = Self;
423
424 fn neg(self) -> Self::Output {
425 self.strict_neg()
426 }
427}
428
429impl RemAssign<Int128> for Int128 {
430 fn rem_assign(&mut self, rhs: Int128) {
431 *self = *self % rhs;
432 }
433}
434forward_ref_op_assign!(impl RemAssign, rem_assign for Int128, Int128);
435
436impl Mul<Int128> for Int128 {
437 type Output = Self;
438
439 fn mul(self, rhs: Self) -> Self::Output {
440 Self(self.0.checked_mul(rhs.0).unwrap())
441 }
442}
443forward_ref_binop!(impl Mul, mul for Int128, Int128);
444
445impl MulAssign<Int128> for Int128 {
446 fn mul_assign(&mut self, rhs: Self) {
447 self.0 = self.0.checked_mul(rhs.0).unwrap();
448 }
449}
450forward_ref_op_assign!(impl MulAssign, mul_assign for Int128, Int128);
451
452impl Shr<u32> for Int128 {
453 type Output = Self;
454
455 fn shr(self, rhs: u32) -> Self::Output {
456 self.checked_shr(rhs).unwrap_or_else(|_| {
457 panic!("right shift error: {rhs} is larger or equal than the number of bits in Int128",)
458 })
459 }
460}
461forward_ref_binop!(impl Shr, shr for Int128, u32);
462
463impl Shl<u32> for Int128 {
464 type Output = Self;
465
466 fn shl(self, rhs: u32) -> Self::Output {
467 self.checked_shl(rhs).unwrap_or_else(|_| {
468 panic!("left shift error: {rhs} is larger or equal than the number of bits in Int128",)
469 })
470 }
471}
472forward_ref_binop!(impl Shl, shl for Int128, u32);
473
474impl AddAssign<Int128> for Int128 {
475 fn add_assign(&mut self, rhs: Int128) {
476 self.0 = self.0.checked_add(rhs.0).unwrap();
477 }
478}
479forward_ref_op_assign!(impl AddAssign, add_assign for Int128, Int128);
480
481impl DivAssign<Int128> for Int128 {
482 fn div_assign(&mut self, rhs: Self) {
483 self.0 = self.0.checked_div(rhs.0).unwrap();
484 }
485}
486forward_ref_op_assign!(impl DivAssign, div_assign for Int128, Int128);
487
488impl ShrAssign<u32> for Int128 {
489 fn shr_assign(&mut self, rhs: u32) {
490 *self = Shr::<u32>::shr(*self, rhs);
491 }
492}
493forward_ref_op_assign!(impl ShrAssign, shr_assign for Int128, u32);
494
495impl ShlAssign<u32> for Int128 {
496 fn shl_assign(&mut self, rhs: u32) {
497 *self = Shl::<u32>::shl(*self, rhs);
498 }
499}
500forward_ref_op_assign!(impl ShlAssign, shl_assign for Int128, u32);
501
502impl<A> core::iter::Sum<A> for Int128
503where
504 Self: Add<A, Output = Self>,
505{
506 fn sum<I: Iterator<Item = A>>(iter: I) -> Self {
507 iter.fold(Self::zero(), Add::add)
508 }
509}
510
511#[cfg(test)]
512mod tests {
513 use super::*;
514 use crate::math::conversion::test_try_from_uint_to_int;
515
516 #[test]
517 fn size_of_works() {
518 assert_eq!(core::mem::size_of::<Int128>(), 16);
519 }
520
521 #[test]
522 fn int128_from_be_bytes_works() {
523 let original = [0; 16];
525 let num = Int128::from_be_bytes(original);
526 assert!(num.is_zero());
527
528 let original = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1];
530 let num = Int128::from_be_bytes(original);
531 assert_eq!(num.i128(), 1);
532
533 let original = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2];
535 let num = Int128::from_be_bytes(original);
536 assert_eq!(num.i128(), 258);
537
538 let original = [1; 16];
540 let num = Int128::from_be_bytes(original);
541 let a: [u8; 16] = num.to_be_bytes();
542 assert_eq!(a, original);
543
544 let original = [
545 0u8, 222u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 2u8, 3u8,
546 ];
547 let num = Int128::from_be_bytes(original);
548 let resulting_bytes: [u8; 16] = num.to_be_bytes();
549 assert_eq!(resulting_bytes, original);
550 }
551
552 #[test]
553 fn int128_from_le_bytes_works() {
554 let original = [0; 16];
556 let num = Int128::from_le_bytes(original);
557 assert!(num.is_zero());
558
559 let original = [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
561 let num = Int128::from_le_bytes(original);
562 assert_eq!(num.i128(), 1);
563
564 let original = [2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
566 let num = Int128::from_le_bytes(original);
567 assert_eq!(num.i128(), 258);
568
569 let original = [1; 16];
571 let num = Int128::from_le_bytes(original);
572 let a: [u8; 16] = num.to_le_bytes();
573 assert_eq!(a, original);
574
575 let original = [
576 0u8, 222u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 2u8, 3u8,
577 ];
578 let num = Int128::from_le_bytes(original);
579 let resulting_bytes: [u8; 16] = num.to_le_bytes();
580 assert_eq!(resulting_bytes, original);
581 }
582
583 #[test]
584 fn int128_new_works() {
585 let num = Int128::new(222);
586 assert_eq!(num.i128(), 222);
587
588 let num = Int128::new(-222);
589 assert_eq!(num.i128(), -222);
590
591 let num = Int128::new(i128::MAX);
592 assert_eq!(num.i128(), i128::MAX);
593
594 let num = Int128::new(i128::MIN);
595 assert_eq!(num.i128(), i128::MIN);
596 }
597
598 #[test]
599 fn int128_not_works() {
600 assert_eq!(!Int128::new(222), Int128::new(!222));
601 assert_eq!(!Int128::new(-222), Int128::new(!-222));
602
603 assert_eq!(!Int128::MAX, Int128::new(!i128::MAX));
604 assert_eq!(!Int128::MIN, Int128::new(!i128::MIN));
605 }
606
607 #[test]
608 fn int128_zero_works() {
609 let zero = Int128::zero();
610 assert_eq!(zero.to_be_bytes(), [0; 16]);
611 }
612
613 #[test]
614 fn uint128_one_works() {
615 let one = Int128::one();
616 let mut one_be = [0; 16];
617 one_be[15] = 1;
618
619 assert_eq!(one.to_be_bytes(), one_be);
620 }
621
622 #[test]
623 fn int128_endianness() {
624 let be_bytes = [
625 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 2u8, 3u8,
626 ];
627 let le_bytes = [
628 3u8, 2u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
629 ];
630
631 let num1 = Int128::from_be_bytes(be_bytes);
633 let num2 = Int128::from_le_bytes(le_bytes);
634 assert_eq!(num1, Int128::from(65536u32 + 512 + 3));
635 assert_eq!(num1, num2);
636 }
637
638 #[test]
639 fn int128_convert_to() {
640 let a = Int128::new(5);
641 assert_eq!(i128::from(a), 5);
642 }
643
644 #[test]
645 fn int128_convert_from() {
646 let a = Int128::from(5i128);
647 assert_eq!(a.0, i128::from(5u32));
648
649 let a = Int128::from(5u64);
650 assert_eq!(a.0, i128::from(5u32));
651
652 let a = Int128::from(5u32);
653 assert_eq!(a.0, i128::from(5u32));
654
655 let a = Int128::from(5u16);
656 assert_eq!(a.0, i128::from(5u32));
657
658 let a = Int128::from(5u8);
659 assert_eq!(a.0, i128::from(5u32));
660
661 let a = Int128::from(-5i128);
662 assert_eq!(a.0, i128::from(-5i32));
663
664 let a = Int128::from(-5i64);
665 assert_eq!(a.0, i128::from(-5i32));
666
667 let a = Int128::from(-5i32);
668 assert_eq!(a.0, i128::from(-5i32));
669
670 let a = Int128::from(-5i16);
671 assert_eq!(a.0, i128::from(-5i32));
672
673 let a = Int128::from(-5i8);
674 assert_eq!(a.0, i128::from(-5i32));
675
676 let result = Int128::try_from("34567");
677 assert_eq!(result.unwrap().0, "34567".parse::<i128>().unwrap());
678
679 let result = Int128::try_from("1.23");
680 assert!(result.is_err());
681 }
682
683 #[test]
684 fn int128_try_from_unsigned_works() {
685 test_try_from_uint_to_int::<Uint128, Int128>("Uint128", "Int128");
686 test_try_from_uint_to_int::<Uint256, Int128>("Uint256", "Int128");
687 test_try_from_uint_to_int::<Uint512, Int128>("Uint512", "Int128");
688 }
689
690 #[test]
691 fn int128_implements_display() {
692 let a = Int128::from(12345u32);
693 assert_eq!(format!("Embedded: {a}"), "Embedded: 12345");
694 assert_eq!(a.to_string(), "12345");
695
696 let a = Int128::from(-12345i32);
697 assert_eq!(format!("Embedded: {a}"), "Embedded: -12345");
698 assert_eq!(a.to_string(), "-12345");
699
700 let a = Int128::zero();
701 assert_eq!(format!("Embedded: {a}"), "Embedded: 0");
702 assert_eq!(a.to_string(), "0");
703 }
704
705 #[test]
706 fn int128_display_padding_works() {
707 let a = Int128::from(123u64);
709 assert_eq!(format!("Embedded: {a:05}"), "Embedded: 00123");
710 let a = Int128::from(-123i64);
711 assert_eq!(format!("Embedded: {a:05}"), "Embedded: -0123");
712
713 let a = Int128::from(123u64);
715 assert_eq!(format!("Embedded: {a:02}"), "Embedded: 123");
716 let a = Int128::from(-123i64);
717 assert_eq!(format!("Embedded: {a:02}"), "Embedded: -123");
718 }
719
720 #[test]
721 fn int128_to_be_bytes_works() {
722 assert_eq!(Int128::zero().to_be_bytes(), [0; 16]);
723
724 let mut max = [0xff; 16];
725 max[0] = 0x7f;
726 assert_eq!(Int128::MAX.to_be_bytes(), max);
727
728 let mut one = [0; 16];
729 one[15] = 1;
730 assert_eq!(Int128::from(1i128).to_be_bytes(), one);
731 assert_eq!(
733 Int128::from(70141183460469231731687303715884018880i128).to_be_bytes(),
734 [52, 196, 179, 87, 165, 121, 59, 133, 246, 117, 221, 191, 255, 254, 172, 192]
735 );
736 assert_eq!(
737 Int128::from_be_bytes([17, 4, 23, 32, 87, 67, 123, 200, 58, 91, 0, 38, 33, 21, 67, 78])
738 .to_be_bytes(),
739 [17, 4, 23, 32, 87, 67, 123, 200, 58, 91, 0, 38, 33, 21, 67, 78]
740 );
741 }
742
743 #[test]
744 fn int128_to_le_bytes_works() {
745 assert_eq!(Int128::zero().to_le_bytes(), [0; 16]);
746
747 let mut max = [0xff; 16];
748 max[15] = 0x7f;
749 assert_eq!(Int128::MAX.to_le_bytes(), max);
750
751 let mut one = [0; 16];
752 one[0] = 1;
753 assert_eq!(Int128::from(1i128).to_le_bytes(), one);
754 assert_eq!(
756 Int128::from(70141183460469231731687303715884018880i128).to_le_bytes(),
757 [192, 172, 254, 255, 191, 221, 117, 246, 133, 59, 121, 165, 87, 179, 196, 52]
758 );
759 assert_eq!(
760 Int128::from_be_bytes([17, 4, 23, 32, 87, 67, 123, 200, 58, 91, 0, 38, 33, 21, 67, 78])
761 .to_le_bytes(),
762 [78, 67, 21, 33, 38, 0, 91, 58, 200, 123, 67, 87, 32, 23, 4, 17]
763 );
764 }
765
766 #[test]
767 fn int128_is_zero_works() {
768 assert!(Int128::zero().is_zero());
769 assert!(Int128(i128::from(0u32)).is_zero());
770
771 assert!(!Int128::from(1u32).is_zero());
772 assert!(!Int128::from(123u32).is_zero());
773 assert!(!Int128::from(-123i32).is_zero());
774 }
775
776 #[test]
777 fn int128_is_negative_works() {
778 assert!(Int128::MIN.is_negative());
779 assert!(Int128::from(-123i32).is_negative());
780
781 assert!(!Int128::MAX.is_negative());
782 assert!(!Int128::zero().is_negative());
783 assert!(!Int128::from(123u32).is_negative());
784 }
785
786 #[test]
787 fn int128_wrapping_methods() {
788 assert_eq!(
790 Int128::from(2u32).wrapping_add(Int128::from(2u32)),
791 Int128::from(4u32)
792 ); assert_eq!(Int128::MAX.wrapping_add(Int128::from(1u32)), Int128::MIN); assert_eq!(
797 Int128::from(7u32).wrapping_sub(Int128::from(5u32)),
798 Int128::from(2u32)
799 ); assert_eq!(Int128::MIN.wrapping_sub(Int128::from(1u32)), Int128::MAX); assert_eq!(
804 Int128::from(3u32).wrapping_mul(Int128::from(2u32)),
805 Int128::from(6u32)
806 ); assert_eq!(
808 Int128::MAX.wrapping_mul(Int128::from(2u32)),
809 Int128::from(-2i32)
810 ); assert_eq!(Int128::from(2u32).wrapping_pow(3), Int128::from(8u32)); assert_eq!(Int128::MAX.wrapping_pow(2), Int128::from(1u32)); }
816
817 #[test]
818 fn int128_json() {
819 let orig = Int128::from(1234567890987654321i128);
820 let serialized = serde_json::to_vec(&orig).unwrap();
821 assert_eq!(serialized.as_slice(), b"\"1234567890987654321\"");
822 let parsed: Int128 = serde_json::from_slice(&serialized).unwrap();
823 assert_eq!(parsed, orig);
824 }
825
826 #[test]
827 fn int128_compare() {
828 let a = Int128::from(12345u32);
829 let b = Int128::from(23456u32);
830
831 assert!(a < b);
832 assert!(b > a);
833 assert_eq!(a, Int128::from(12345u32));
834 }
835
836 #[test]
837 #[allow(clippy::op_ref)]
838 fn int128_math() {
839 let a = Int128::from(-12345i32);
840 let b = Int128::from(23456u32);
841
842 assert_eq!(a + b, Int128::from(11111u32));
844 assert_eq!(a + &b, Int128::from(11111u32));
845
846 assert_eq!(b - a, Int128::from(35801u32));
848 assert_eq!(b - &a, Int128::from(35801u32));
849
850 let mut c = Int128::from(300000u32);
852 c += b;
853 assert_eq!(c, Int128::from(323456u32));
854 let mut d = Int128::from(300000u32);
855 d += &b;
856 assert_eq!(d, Int128::from(323456u32));
857
858 let mut c = Int128::from(300000u32);
860 c -= b;
861 assert_eq!(c, Int128::from(276544u32));
862 let mut d = Int128::from(300000u32);
863 d -= &b;
864 assert_eq!(d, Int128::from(276544u32));
865
866 assert_eq!(a - b, Int128::from(-35801i32));
868 }
869
870 #[test]
871 #[should_panic]
872 fn int128_add_overflow_panics() {
873 let _ = Int128::MAX + Int128::from(12u32);
874 }
875
876 #[test]
877 #[allow(clippy::op_ref)]
878 fn int128_sub_works() {
879 assert_eq!(Int128::from(2u32) - Int128::from(1u32), Int128::from(1u32));
880 assert_eq!(Int128::from(2u32) - Int128::from(0u32), Int128::from(2u32));
881 assert_eq!(Int128::from(2u32) - Int128::from(2u32), Int128::from(0u32));
882 assert_eq!(Int128::from(2u32) - Int128::from(3u32), Int128::from(-1i32));
883
884 let a = Int128::from(10u32);
886 let b = Int128::from(3u32);
887 let expected = Int128::from(7u32);
888 assert_eq!(a - b, expected);
889 assert_eq!(a - &b, expected);
890 assert_eq!(&a - b, expected);
891 assert_eq!(&a - &b, expected);
892 }
893
894 #[test]
895 #[should_panic]
896 fn int128_sub_overflow_panics() {
897 let _ = Int128::MIN + Int128::one() - Int128::from(2u32);
898 }
899
900 #[test]
901 fn int128_sub_assign_works() {
902 let mut a = Int128::from(14u32);
903 a -= Int128::from(2u32);
904 assert_eq!(a, Int128::from(12u32));
905
906 let mut a = Int128::from(10u32);
908 let b = Int128::from(3u32);
909 let expected = Int128::from(7u32);
910 a -= &b;
911 assert_eq!(a, expected);
912 }
913
914 #[test]
915 #[allow(clippy::op_ref)]
916 fn int128_mul_works() {
917 assert_eq!(Int128::from(2u32) * Int128::from(3u32), Int128::from(6u32));
918 assert_eq!(Int128::from(2u32) * Int128::zero(), Int128::zero());
919
920 let a = Int128::from(11u32);
922 let b = Int128::from(3u32);
923 let expected = Int128::from(33u32);
924 assert_eq!(a * b, expected);
925 assert_eq!(a * &b, expected);
926 assert_eq!(&a * b, expected);
927 assert_eq!(&a * &b, expected);
928 }
929
930 #[test]
931 fn int128_mul_assign_works() {
932 let mut a = Int128::from(14u32);
933 a *= Int128::from(2u32);
934 assert_eq!(a, Int128::from(28u32));
935
936 let mut a = Int128::from(10u32);
938 let b = Int128::from(3u32);
939 a *= &b;
940 assert_eq!(a, Int128::from(30u32));
941 }
942
943 #[test]
944 fn int128_pow_works() {
945 assert_eq!(Int128::from(2u32).pow(2), Int128::from(4u32));
946 assert_eq!(Int128::from(2u32).pow(10), Int128::from(1024u32));
947 }
948
949 #[test]
950 #[should_panic]
951 fn int128_pow_overflow_panics() {
952 _ = Int128::MAX.pow(2u32);
953 }
954
955 #[test]
956 fn int128_checked_multiply_ratio_works() {
957 let base = Int128(500);
958
959 assert_eq!(base.checked_multiply_ratio(1i128, 1i128).unwrap(), base);
961 assert_eq!(base.checked_multiply_ratio(3i128, 3i128).unwrap(), base);
962 assert_eq!(
963 base.checked_multiply_ratio(654321i128, 654321i128).unwrap(),
964 base
965 );
966 assert_eq!(
967 base.checked_multiply_ratio(i128::MAX, i128::MAX).unwrap(),
968 base
969 );
970
971 assert_eq!(
973 base.checked_multiply_ratio(3i128, 2i128).unwrap(),
974 Int128(750)
975 );
976 assert_eq!(
977 base.checked_multiply_ratio(333333i128, 222222i128).unwrap(),
978 Int128(750)
979 );
980
981 assert_eq!(
983 base.checked_multiply_ratio(2i128, 3i128).unwrap(),
984 Int128(333)
985 );
986 assert_eq!(
987 base.checked_multiply_ratio(222222i128, 333333i128).unwrap(),
988 Int128(333)
989 );
990
991 assert_eq!(
993 base.checked_multiply_ratio(5i128, 6i128).unwrap(),
994 Int128(416)
995 );
996 assert_eq!(
997 base.checked_multiply_ratio(100i128, 120i128).unwrap(),
998 Int128(416)
999 );
1000 }
1001
1002 #[test]
1003 fn int128_checked_multiply_ratio_does_not_panic() {
1004 assert_eq!(
1005 Int128(500i128).checked_multiply_ratio(1i128, 0i128),
1006 Err(CheckedMultiplyRatioError::DivideByZero),
1007 );
1008 assert_eq!(
1009 Int128(500i128).checked_multiply_ratio(i128::MAX, 1i128),
1010 Err(CheckedMultiplyRatioError::Overflow),
1011 );
1012 }
1013
1014 #[test]
1015 fn int128_shr_works() {
1016 let original = Int128::from_be_bytes([
1017 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 4u8, 2u8,
1018 ]);
1019
1020 let shifted = Int128::from_be_bytes([
1021 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 128u8, 1u8, 0u8,
1022 ]);
1023
1024 assert_eq!(original >> 2u32, shifted);
1025 }
1026
1027 #[test]
1028 #[should_panic]
1029 fn int128_shr_overflow_panics() {
1030 let _ = Int128::from(1u32) >> 128u32;
1031 }
1032
1033 #[test]
1034 fn sum_works() {
1035 let nums = vec![
1036 Int128::from(17u32),
1037 Int128::from(123u32),
1038 Int128::from(540u32),
1039 Int128::from(82u32),
1040 ];
1041 let expected = Int128::from(762u32);
1042
1043 let sum_as_ref: Int128 = nums.iter().sum();
1044 assert_eq!(expected, sum_as_ref);
1045
1046 let sum_as_owned: Int128 = nums.into_iter().sum();
1047 assert_eq!(expected, sum_as_owned);
1048 }
1049
1050 #[test]
1051 fn int128_methods() {
1052 assert!(matches!(
1054 Int128::MAX.checked_add(Int128::from(1u32)),
1055 Err(OverflowError { .. })
1056 ));
1057 assert_eq!(
1058 Int128::from(1u32).checked_add(Int128::from(1u32)),
1059 Ok(Int128::from(2u32)),
1060 );
1061 assert!(matches!(
1062 Int128::MIN.checked_sub(Int128::from(1u32)),
1063 Err(OverflowError { .. })
1064 ));
1065 assert_eq!(
1066 Int128::from(2u32).checked_sub(Int128::from(1u32)),
1067 Ok(Int128::from(1u32)),
1068 );
1069 assert!(matches!(
1070 Int128::MAX.checked_mul(Int128::from(2u32)),
1071 Err(OverflowError { .. })
1072 ));
1073 assert_eq!(
1074 Int128::from(2u32).checked_mul(Int128::from(2u32)),
1075 Ok(Int128::from(4u32)),
1076 );
1077 assert!(matches!(
1078 Int128::MAX.checked_pow(2u32),
1079 Err(OverflowError { .. })
1080 ));
1081 assert_eq!(Int128::from(2u32).checked_pow(3u32), Ok(Int128::from(8u32)),);
1082 assert_eq!(
1083 Int128::MAX.checked_div(Int128::from(0u32)),
1084 Err(DivisionError::DivideByZero)
1085 );
1086 assert_eq!(
1087 Int128::from(6u32).checked_div(Int128::from(2u32)),
1088 Ok(Int128::from(3u32)),
1089 );
1090 assert_eq!(
1091 Int128::MAX.checked_div_euclid(Int128::from(0u32)),
1092 Err(DivisionError::DivideByZero)
1093 );
1094 assert_eq!(
1095 Int128::from(6u32).checked_div_euclid(Int128::from(2u32)),
1096 Ok(Int128::from(3u32)),
1097 );
1098 assert_eq!(
1099 Int128::from(7u32).checked_div_euclid(Int128::from(2u32)),
1100 Ok(Int128::from(3u32)),
1101 );
1102 assert!(matches!(
1103 Int128::MAX.checked_rem(Int128::from(0u32)),
1104 Err(DivideByZeroError { .. })
1105 ));
1106 assert_eq!(
1108 Int128::from(-12i32).checked_div(Int128::from(10i32)),
1109 Ok(Int128::from(-1i32)),
1110 );
1111 assert_eq!(
1112 Int128::from(-2i32).checked_pow(3u32),
1113 Ok(Int128::from(-8i32)),
1114 );
1115 assert_eq!(
1116 Int128::from(-6i32).checked_mul(Int128::from(-7i32)),
1117 Ok(Int128::from(42i32)),
1118 );
1119 assert_eq!(
1120 Int128::from(-2i32).checked_add(Int128::from(3i32)),
1121 Ok(Int128::from(1i32)),
1122 );
1123 assert_eq!(
1124 Int128::from(-1i32).checked_div_euclid(Int128::from(-2i32)),
1125 Ok(Int128::from(1u32)),
1126 );
1127
1128 assert_eq!(Int128::MAX.saturating_add(Int128::from(1u32)), Int128::MAX);
1130 assert_eq!(Int128::MIN.saturating_sub(Int128::from(1u32)), Int128::MIN);
1131 assert_eq!(Int128::MAX.saturating_mul(Int128::from(2u32)), Int128::MAX);
1132 assert_eq!(Int128::from(4u32).saturating_pow(2u32), Int128::from(16u32));
1133 assert_eq!(Int128::MAX.saturating_pow(2u32), Int128::MAX);
1134 }
1135
1136 #[test]
1137 #[allow(clippy::op_ref)]
1138 fn int128_implements_rem() {
1139 let a = Int128::from(10u32);
1140 assert_eq!(a % Int128::from(10u32), Int128::zero());
1141 assert_eq!(a % Int128::from(2u32), Int128::zero());
1142 assert_eq!(a % Int128::from(1u32), Int128::zero());
1143 assert_eq!(a % Int128::from(3u32), Int128::from(1u32));
1144 assert_eq!(a % Int128::from(4u32), Int128::from(2u32));
1145
1146 assert_eq!(
1147 Int128::from(-12i32) % Int128::from(10i32),
1148 Int128::from(-2i32)
1149 );
1150 assert_eq!(
1151 Int128::from(12i32) % Int128::from(-10i32),
1152 Int128::from(2i32)
1153 );
1154 assert_eq!(
1155 Int128::from(-12i32) % Int128::from(-10i32),
1156 Int128::from(-2i32)
1157 );
1158
1159 let a = Int128::from(10u32);
1161 let b = Int128::from(3u32);
1162 let expected = Int128::from(1u32);
1163 assert_eq!(a % b, expected);
1164 assert_eq!(a % &b, expected);
1165 assert_eq!(&a % b, expected);
1166 assert_eq!(&a % &b, expected);
1167 }
1168
1169 #[test]
1170 #[should_panic(expected = "divisor of zero")]
1171 fn int128_rem_panics_for_zero() {
1172 let _ = Int128::from(10u32) % Int128::zero();
1173 }
1174
1175 #[test]
1176 fn int128_rem_assign_works() {
1177 let mut a = Int128::from(30u32);
1178 a %= Int128::from(4u32);
1179 assert_eq!(a, Int128::from(2u32));
1180
1181 let mut a = Int128::from(25u32);
1183 let b = Int128::from(6u32);
1184 a %= &b;
1185 assert_eq!(a, Int128::from(1u32));
1186 }
1187
1188 #[test]
1189 fn int128_shr() {
1190 let x: Int128 = 0x4000_0000_0000_0000_0000_0000_0000_0000i128.into();
1191 assert_eq!(x >> 0, x); assert_eq!(
1193 x >> 1,
1194 Int128::from(0x2000_0000_0000_0000_0000_0000_0000_0000i128)
1195 );
1196 assert_eq!(
1197 x >> 4,
1198 Int128::from(0x0400_0000_0000_0000_0000_0000_0000_0000i128)
1199 );
1200 assert_eq!(
1202 Int128::MIN >> (core::mem::size_of::<Int128>() as u32 * 8 - 1),
1203 -Int128::one()
1204 );
1205 }
1206
1207 #[test]
1208 fn int128_shl() {
1209 let x: Int128 = 0x0800_0000_0000_0000_0000_0000_0000_0000i128.into();
1210 assert_eq!(x << 0, x); assert_eq!(
1212 x << 1,
1213 Int128::from(0x1000_0000_0000_0000_0000_0000_0000_0000i128)
1214 );
1215 assert_eq!(
1216 x << 4,
1217 Int128::from(0x0800_0000_0000_0000_0000_0000_0000_0000i128 << 4)
1218 );
1219 assert_eq!(
1221 Int128::one() << (core::mem::size_of::<Int128>() as u32 * 8 - 1),
1222 Int128::MIN
1223 );
1224 }
1225
1226 #[test]
1227 fn int128_abs_diff_works() {
1228 let a = Int128::from(42u32);
1229 let b = Int128::from(5u32);
1230 let expected = Uint128::from(37u32);
1231 assert_eq!(a.abs_diff(b), expected);
1232 assert_eq!(b.abs_diff(a), expected);
1233
1234 let c = Int128::from(-5i32);
1235 assert_eq!(b.abs_diff(c), Uint128::from(10u32));
1236 assert_eq!(c.abs_diff(b), Uint128::from(10u32));
1237 }
1238
1239 #[test]
1240 fn int128_abs_works() {
1241 let a = Int128::from(42i32);
1242 assert_eq!(a.abs(), a);
1243
1244 let b = Int128::from(-42i32);
1245 assert_eq!(b.abs(), a);
1246
1247 assert_eq!(Int128::zero().abs(), Int128::zero());
1248 assert_eq!((Int128::MIN + Int128::one()).abs(), Int128::MAX);
1249 }
1250
1251 #[test]
1252 fn int128_unsigned_abs_works() {
1253 assert_eq!(Int128::zero().unsigned_abs(), Uint128::zero());
1254 assert_eq!(Int128::one().unsigned_abs(), Uint128::one());
1255 assert_eq!(
1256 Int128::MIN.unsigned_abs(),
1257 Uint128::new(Int128::MAX.0 as u128) + Uint128::one()
1258 );
1259
1260 let v = Int128::from(-42i32);
1261 assert_eq!(v.unsigned_abs(), v.abs_diff(Int128::zero()));
1262 }
1263
1264 #[test]
1265 #[should_panic = "attempt to calculate absolute value with overflow"]
1266 fn int128_abs_min_panics() {
1267 _ = Int128::MIN.abs();
1268 }
1269
1270 #[test]
1271 #[should_panic = "attempt to negate with overflow"]
1272 fn int128_neg_min_panics() {
1273 _ = -Int128::MIN;
1274 }
1275
1276 #[test]
1277 fn int128_partial_eq() {
1278 let test_cases = [(1, 1, true), (42, 42, true), (42, 24, false), (0, 0, true)]
1279 .into_iter()
1280 .map(|(lhs, rhs, expected): (u64, u64, bool)| {
1281 (Int128::from(lhs), Int128::from(rhs), expected)
1282 });
1283
1284 #[allow(clippy::op_ref)]
1285 for (lhs, rhs, expected) in test_cases {
1286 assert_eq!(lhs == rhs, expected);
1287 assert_eq!(&lhs == rhs, expected);
1288 assert_eq!(lhs == &rhs, expected);
1289 assert_eq!(&lhs == &rhs, expected);
1290 }
1291 }
1292}