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