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