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