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, Int128, Int512, Int64, Uint128, Uint256, Uint512, Uint64,
13 __internal::forward_ref_partial_eq,
14};
15
16use bnum::types::{I256, U256};
19
20use super::conversion::{
21 grow_be_int, primitive_to_wrapped_int, try_from_int_to_int, try_from_uint_to_int,
22};
23use super::impl_int_serde;
24use super::num_consts::NumConsts;
25
26#[derive(Copy, Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord, schemars::JsonSchema)]
49pub struct Int256(#[schemars(with = "String")] pub(crate) I256);
50
51impl_int_serde!(Int256);
52forward_ref_partial_eq!(Int256, Int256);
53
54impl Int256 {
55 pub const MAX: Int256 = Int256(I256::MAX);
56 pub const MIN: Int256 = Int256(I256::MIN);
57
58 #[inline]
67 #[must_use]
68 pub const fn new(value: i128) -> Self {
69 Self::from_be_bytes(grow_be_int(value.to_be_bytes()))
70 }
71
72 #[inline]
74 pub const fn zero() -> Self {
75 Int256(I256::ZERO)
76 }
77
78 #[inline]
80 pub const fn one() -> Self {
81 Self(I256::ONE)
82 }
83
84 #[deprecated(since = "3.0.0", note = "Use Int256::new(value) instead")]
87 pub const fn from_i128(value: i128) -> Self {
88 Self::new(value)
89 }
90
91 #[must_use]
92 pub const fn from_be_bytes(data: [u8; 32]) -> Self {
93 let words: [u64; 4] = [
94 u64::from_le_bytes([
95 data[31], data[30], data[29], data[28], data[27], data[26], data[25], data[24],
96 ]),
97 u64::from_le_bytes([
98 data[23], data[22], data[21], data[20], data[19], data[18], data[17], data[16],
99 ]),
100 u64::from_le_bytes([
101 data[15], data[14], data[13], data[12], data[11], data[10], data[9], data[8],
102 ]),
103 u64::from_le_bytes([
104 data[7], data[6], data[5], data[4], data[3], data[2], data[1], data[0],
105 ]),
106 ];
107 Self(I256::from_bits(U256::from_digits(words)))
108 }
109
110 #[must_use]
111 pub const fn from_le_bytes(data: [u8; 32]) -> Self {
112 let words: [u64; 4] = [
113 u64::from_le_bytes([
114 data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7],
115 ]),
116 u64::from_le_bytes([
117 data[8], data[9], data[10], data[11], data[12], data[13], data[14], data[15],
118 ]),
119 u64::from_le_bytes([
120 data[16], data[17], data[18], data[19], data[20], data[21], data[22], data[23],
121 ]),
122 u64::from_le_bytes([
123 data[24], data[25], data[26], data[27], data[28], data[29], data[30], data[31],
124 ]),
125 ];
126 Self(I256::from_bits(U256::from_digits(words)))
127 }
128
129 #[must_use = "this returns the result of the operation, without modifying the original"]
131 pub const fn to_be_bytes(self) -> [u8; 32] {
132 let bits = self.0.to_bits();
133 let words = bits.digits();
134 let words = [
135 words[3].to_be_bytes(),
136 words[2].to_be_bytes(),
137 words[1].to_be_bytes(),
138 words[0].to_be_bytes(),
139 ];
140 unsafe { core::mem::transmute::<[[u8; 8]; 4], [u8; 32]>(words) }
141 }
142
143 #[must_use = "this returns the result of the operation, without modifying the original"]
145 pub const fn to_le_bytes(self) -> [u8; 32] {
146 let bits = self.0.to_bits();
147 let words = bits.digits();
148 let words = [
149 words[0].to_le_bytes(),
150 words[1].to_le_bytes(),
151 words[2].to_le_bytes(),
152 words[3].to_le_bytes(),
153 ];
154 unsafe { core::mem::transmute::<[[u8; 8]; 4], [u8; 32]>(words) }
155 }
156
157 #[must_use]
158 pub const fn is_zero(&self) -> bool {
159 self.0.is_zero()
160 }
161
162 #[must_use]
163 pub const fn is_negative(&self) -> bool {
164 self.0.is_negative()
165 }
166
167 #[must_use = "this returns the result of the operation, without modifying the original"]
168 pub const fn pow(self, exp: u32) -> Self {
169 match self.0.checked_pow(exp) {
170 Some(val) => Self(val),
171 None => panic!("attempt to exponentiate with overflow"),
172 }
173 }
174
175 pub fn checked_multiply_ratio<A: Into<Self>, B: Into<Self>>(
180 &self,
181 numerator: A,
182 denominator: B,
183 ) -> Result<Self, CheckedMultiplyRatioError> {
184 let numerator = numerator.into();
185 let denominator = denominator.into();
186 if denominator.is_zero() {
187 return Err(CheckedMultiplyRatioError::DivideByZero);
188 }
189 match (self.full_mul(numerator) / Int512::from(denominator)).try_into() {
190 Ok(ratio) => Ok(ratio),
191 Err(_) => Err(CheckedMultiplyRatioError::Overflow),
192 }
193 }
194
195 #[must_use = "this returns the result of the operation, without modifying the original"]
211 pub fn full_mul(self, rhs: impl Into<Self>) -> Int512 {
212 Int512::from(self)
213 .checked_mul(Int512::from(rhs.into()))
214 .unwrap()
215 }
216
217 pub fn checked_add(self, other: Self) -> Result<Self, OverflowError> {
218 self.0
219 .checked_add(other.0)
220 .map(Self)
221 .ok_or_else(|| OverflowError::new(OverflowOperation::Add))
222 }
223
224 pub fn checked_sub(self, other: Self) -> Result<Self, OverflowError> {
225 self.0
226 .checked_sub(other.0)
227 .map(Self)
228 .ok_or_else(|| OverflowError::new(OverflowOperation::Sub))
229 }
230
231 pub fn checked_mul(self, other: Self) -> Result<Self, OverflowError> {
232 self.0
233 .checked_mul(other.0)
234 .map(Self)
235 .ok_or_else(|| OverflowError::new(OverflowOperation::Mul))
236 }
237
238 pub fn checked_pow(self, exp: u32) -> Result<Self, OverflowError> {
239 self.0
240 .checked_pow(exp)
241 .map(Self)
242 .ok_or_else(|| OverflowError::new(OverflowOperation::Pow))
243 }
244
245 pub fn checked_div(self, other: Self) -> Result<Self, DivisionError> {
246 if other.is_zero() {
247 return Err(DivisionError::DivideByZero);
248 }
249 self.0
250 .checked_div(other.0)
251 .map(Self)
252 .ok_or(DivisionError::Overflow)
253 }
254
255 pub fn checked_div_euclid(self, other: Self) -> Result<Self, DivisionError> {
256 if other.is_zero() {
257 return Err(DivisionError::DivideByZero);
258 }
259 self.0
260 .checked_div_euclid(other.0)
261 .map(Self)
262 .ok_or(DivisionError::Overflow)
263 }
264
265 pub fn checked_rem(self, other: Self) -> Result<Self, DivideByZeroError> {
266 self.0
267 .checked_rem(other.0)
268 .map(Self)
269 .ok_or(DivideByZeroError)
270 }
271
272 pub fn checked_shr(self, other: u32) -> Result<Self, OverflowError> {
273 if other >= 256 {
274 return Err(OverflowError::new(OverflowOperation::Shr));
275 }
276
277 Ok(Self(self.0.shr(other)))
278 }
279
280 pub fn checked_shl(self, other: u32) -> Result<Self, OverflowError> {
281 if other >= 256 {
282 return Err(OverflowError::new(OverflowOperation::Shl));
283 }
284
285 Ok(Self(self.0.shl(other)))
286 }
287
288 #[must_use = "this returns the result of the operation, without modifying the original"]
289 #[inline]
290 pub fn wrapping_add(self, other: Self) -> Self {
291 Self(self.0.wrapping_add(other.0))
292 }
293
294 #[must_use = "this returns the result of the operation, without modifying the original"]
295 #[inline]
296 pub fn wrapping_sub(self, other: Self) -> Self {
297 Self(self.0.wrapping_sub(other.0))
298 }
299
300 #[must_use = "this returns the result of the operation, without modifying the original"]
301 #[inline]
302 pub fn wrapping_mul(self, other: Self) -> Self {
303 Self(self.0.wrapping_mul(other.0))
304 }
305
306 #[must_use = "this returns the result of the operation, without modifying the original"]
307 #[inline]
308 pub fn wrapping_pow(self, other: u32) -> Self {
309 Self(self.0.wrapping_pow(other))
310 }
311
312 #[must_use = "this returns the result of the operation, without modifying the original"]
313 pub fn saturating_add(self, other: Self) -> Self {
314 Self(self.0.saturating_add(other.0))
315 }
316
317 #[must_use = "this returns the result of the operation, without modifying the original"]
318 pub fn saturating_sub(self, other: Self) -> Self {
319 Self(self.0.saturating_sub(other.0))
320 }
321
322 #[must_use = "this returns the result of the operation, without modifying the original"]
323 pub fn saturating_mul(self, other: Self) -> Self {
324 Self(self.0.saturating_mul(other.0))
325 }
326
327 #[must_use = "this returns the result of the operation, without modifying the original"]
328 pub fn saturating_pow(self, exp: u32) -> Self {
329 Self(self.0.saturating_pow(exp))
330 }
331
332 #[must_use = "this returns the result of the operation, without modifying the original"]
333 pub const fn abs_diff(self, other: Self) -> Uint256 {
334 Uint256(self.0.abs_diff(other.0))
335 }
336
337 #[must_use = "this returns the result of the operation, without modifying the original"]
338 pub const fn abs(self) -> Self {
339 match self.0.checked_abs() {
340 Some(val) => Self(val),
341 None => panic!("attempt to calculate absolute value with overflow"),
342 }
343 }
344
345 #[must_use = "this returns the result of the operation, without modifying the original"]
346 pub const fn unsigned_abs(self) -> Uint256 {
347 Uint256(self.0.unsigned_abs())
348 }
349
350 pub const fn strict_neg(self) -> Self {
354 match self.0.checked_neg() {
355 Some(val) => Self(val),
356 None => panic!("attempt to negate with overflow"),
357 }
358 }
359}
360
361impl NumConsts for Int256 {
362 const ZERO: Self = Self::zero();
363 const ONE: Self = Self::one();
364 const MAX: Self = Self::MAX;
365 const MIN: Self = Self::MIN;
366}
367
368try_from_uint_to_int!(Uint512, Int256);
370try_from_uint_to_int!(Uint256, Int256);
371
372impl From<Uint128> for Int256 {
373 fn from(val: Uint128) -> Self {
374 val.u128().into()
375 }
376}
377
378impl From<Uint64> for Int256 {
379 fn from(val: Uint64) -> Self {
380 val.u64().into()
381 }
382}
383
384primitive_to_wrapped_int!(u8, Int256);
386primitive_to_wrapped_int!(u16, Int256);
387primitive_to_wrapped_int!(u32, Int256);
388primitive_to_wrapped_int!(u64, Int256);
389primitive_to_wrapped_int!(u128, Int256);
390
391try_from_int_to_int!(Int512, Int256);
393
394impl From<Int128> for Int256 {
395 fn from(val: Int128) -> Self {
396 val.i128().into()
397 }
398}
399
400impl From<Int64> for Int256 {
401 fn from(val: Int64) -> Self {
402 val.i64().into()
403 }
404}
405
406primitive_to_wrapped_int!(i8, Int256);
408primitive_to_wrapped_int!(i16, Int256);
409primitive_to_wrapped_int!(i32, Int256);
410primitive_to_wrapped_int!(i64, Int256);
411primitive_to_wrapped_int!(i128, Int256);
412
413impl TryFrom<&str> for Int256 {
414 type Error = StdError;
415
416 fn try_from(val: &str) -> Result<Self, Self::Error> {
417 Self::from_str(val)
418 }
419}
420
421impl FromStr for Int256 {
422 type Err = StdError;
423
424 fn from_str(s: &str) -> Result<Self, Self::Err> {
425 match I256::from_str_radix(s, 10) {
426 Ok(u) => Ok(Self(u)),
427 Err(e) => Err(StdError::generic_err(format!("Parsing Int256: {e}"))),
428 }
429 }
430}
431
432impl From<Int256> for String {
433 fn from(original: Int256) -> Self {
434 original.to_string()
435 }
436}
437
438impl fmt::Display for Int256 {
439 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
440 self.0.fmt(f)
441 }
442}
443
444impl Add<Int256> for Int256 {
445 type Output = Self;
446
447 fn add(self, rhs: Self) -> Self {
448 Int256(self.0.checked_add(rhs.0).unwrap())
449 }
450}
451forward_ref_binop!(impl Add, add for Int256, Int256);
452
453impl Sub<Int256> for Int256 {
454 type Output = Self;
455
456 fn sub(self, rhs: Self) -> Self {
457 Int256(self.0.checked_sub(rhs.0).unwrap())
458 }
459}
460forward_ref_binop!(impl Sub, sub for Int256, Int256);
461
462impl SubAssign<Int256> for Int256 {
463 fn sub_assign(&mut self, rhs: Int256) {
464 self.0 = self.0.checked_sub(rhs.0).unwrap();
465 }
466}
467forward_ref_op_assign!(impl SubAssign, sub_assign for Int256, Int256);
468
469impl Div<Int256> for Int256 {
470 type Output = Self;
471
472 fn div(self, rhs: Self) -> Self::Output {
473 Self(self.0.checked_div(rhs.0).unwrap())
474 }
475}
476forward_ref_binop!(impl Div, div for Int256, Int256);
477
478impl Rem for Int256 {
479 type Output = Self;
480
481 #[inline]
485 fn rem(self, rhs: Self) -> Self {
486 Self(self.0.rem(rhs.0))
487 }
488}
489forward_ref_binop!(impl Rem, rem for Int256, Int256);
490
491impl Not for Int256 {
492 type Output = Self;
493
494 fn not(self) -> Self::Output {
495 Self(!self.0)
496 }
497}
498
499impl Neg for Int256 {
500 type Output = Self;
501
502 fn neg(self) -> Self::Output {
503 self.strict_neg()
504 }
505}
506
507impl RemAssign<Int256> for Int256 {
508 fn rem_assign(&mut self, rhs: Int256) {
509 *self = *self % rhs;
510 }
511}
512forward_ref_op_assign!(impl RemAssign, rem_assign for Int256, Int256);
513
514impl Mul<Int256> for Int256 {
515 type Output = Self;
516
517 fn mul(self, rhs: Self) -> Self::Output {
518 Self(self.0.checked_mul(rhs.0).unwrap())
519 }
520}
521forward_ref_binop!(impl Mul, mul for Int256, Int256);
522
523impl MulAssign<Int256> for Int256 {
524 fn mul_assign(&mut self, rhs: Self) {
525 self.0 = self.0.checked_mul(rhs.0).unwrap();
526 }
527}
528forward_ref_op_assign!(impl MulAssign, mul_assign for Int256, Int256);
529
530impl Shr<u32> for Int256 {
531 type Output = Self;
532
533 fn shr(self, rhs: u32) -> Self::Output {
534 self.checked_shr(rhs).unwrap_or_else(|_| {
535 panic!("right shift error: {rhs} is larger or equal than the number of bits in Int256",)
536 })
537 }
538}
539forward_ref_binop!(impl Shr, shr for Int256, u32);
540
541impl Shl<u32> for Int256 {
542 type Output = Self;
543
544 fn shl(self, rhs: u32) -> Self::Output {
545 self.checked_shl(rhs).unwrap_or_else(|_| {
546 panic!("left shift error: {rhs} is larger or equal than the number of bits in Int256",)
547 })
548 }
549}
550forward_ref_binop!(impl Shl, shl for Int256, u32);
551
552impl AddAssign<Int256> for Int256 {
553 fn add_assign(&mut self, rhs: Int256) {
554 self.0 = self.0.checked_add(rhs.0).unwrap();
555 }
556}
557forward_ref_op_assign!(impl AddAssign, add_assign for Int256, Int256);
558
559impl DivAssign<Int256> for Int256 {
560 fn div_assign(&mut self, rhs: Self) {
561 self.0 = self.0.checked_div(rhs.0).unwrap();
562 }
563}
564forward_ref_op_assign!(impl DivAssign, div_assign for Int256, Int256);
565
566impl ShrAssign<u32> for Int256 {
567 fn shr_assign(&mut self, rhs: u32) {
568 *self = Shr::<u32>::shr(*self, rhs);
569 }
570}
571forward_ref_op_assign!(impl ShrAssign, shr_assign for Int256, u32);
572
573impl ShlAssign<u32> for Int256 {
574 fn shl_assign(&mut self, rhs: u32) {
575 *self = Shl::<u32>::shl(*self, rhs);
576 }
577}
578forward_ref_op_assign!(impl ShlAssign, shl_assign for Int256, u32);
579
580impl<A> core::iter::Sum<A> for Int256
581where
582 Self: Add<A, Output = Self>,
583{
584 fn sum<I: Iterator<Item = A>>(iter: I) -> Self {
585 iter.fold(Self::zero(), Add::add)
586 }
587}
588
589#[cfg(test)]
590mod tests {
591 use super::*;
592 use crate::math::conversion::test_try_from_uint_to_int;
593
594 #[test]
595 fn size_of_works() {
596 assert_eq!(core::mem::size_of::<Int256>(), 32);
597 }
598
599 #[test]
600 fn int256_new_works() {
601 let num = Int256::new(1);
602 assert_eq!(
603 num.to_be_bytes(),
604 [
605 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
606 0, 0, 0, 1
607 ]
608 );
609
610 let num = Int256::new(-1);
611 assert_eq!(
612 num.to_be_bytes(),
613 [
614 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
615 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
616 ]
617 );
618
619 for v in [0, 1, -4, 18, 875786576, -11763498739, i128::MAX, i128::MIN] {
620 let uut = Int256::new(v);
622 assert_eq!(uut, Int256::from(v));
623 }
624 }
625
626 #[test]
627 fn int256_from_be_bytes_works() {
628 let num = Int256::from_be_bytes([1; 32]);
629 let a: [u8; 32] = num.to_be_bytes();
630 assert_eq!(a, [1; 32]);
631
632 let be_bytes = [
633 0u8, 222u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
634 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 2u8, 3u8,
635 ];
636 let num = Int256::from_be_bytes(be_bytes);
637 let resulting_bytes: [u8; 32] = num.to_be_bytes();
638 assert_eq!(be_bytes, resulting_bytes);
639 }
640
641 #[test]
642 fn int256_not_works() {
643 let num = Int256::from_be_bytes([1; 32]);
644 let a = (!num).to_be_bytes();
645 assert_eq!(a, [254; 32]);
646
647 assert_eq!(!Int256::from(-1234806i128), Int256::from(!-1234806i128));
648
649 assert_eq!(!Int256::MAX, Int256::MIN);
650 assert_eq!(!Int256::MIN, Int256::MAX);
651 }
652
653 #[test]
654 fn int256_zero_works() {
655 let zero = Int256::zero();
656 assert_eq!(zero.to_be_bytes(), [0; 32]);
657 }
658
659 #[test]
660 fn uint256_one_works() {
661 let one = Int256::one();
662 let mut one_be = [0; 32];
663 one_be[31] = 1;
664
665 assert_eq!(one.to_be_bytes(), one_be);
666 }
667
668 #[test]
669 fn int256_endianness() {
670 let be_bytes = [
671 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
672 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 2u8, 3u8,
673 ];
674 let le_bytes = [
675 3u8, 2u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
676 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
677 ];
678
679 let a = Int256::from_be_bytes(be_bytes);
681 let b = Int256::from_le_bytes(le_bytes);
682 assert_eq!(a, Int256::from(65536u32 + 512 + 3));
683 assert_eq!(a, b);
684 }
685
686 #[test]
687 fn int256_convert_from() {
688 let a = Int256::from(5u128);
689 assert_eq!(a.0, I256::from(5u32));
690
691 let a = Int256::from(5u64);
692 assert_eq!(a.0, I256::from(5u32));
693
694 let a = Int256::from(5u32);
695 assert_eq!(a.0, I256::from(5u32));
696
697 let a = Int256::from(5u16);
698 assert_eq!(a.0, I256::from(5u32));
699
700 let a = Int256::from(5u8);
701 assert_eq!(a.0, I256::from(5u32));
702
703 let a = Int256::from(-5i128);
704 assert_eq!(a.0, I256::from(-5i32));
705
706 let a = Int256::from(-5i64);
707 assert_eq!(a.0, I256::from(-5i32));
708
709 let a = Int256::from(-5i32);
710 assert_eq!(a.0, I256::from(-5i32));
711
712 let a = Int256::from(-5i16);
713 assert_eq!(a.0, I256::from(-5i32));
714
715 let a = Int256::from(-5i8);
716 assert_eq!(a.0, I256::from(-5i32));
717
718 let result = Int256::try_from("34567");
719 assert_eq!(
720 result.unwrap().0,
721 I256::from_str_radix("34567", 10).unwrap()
722 );
723
724 let result = Int256::try_from("1.23");
725 assert!(result.is_err());
726 }
727
728 #[test]
729 fn int256_try_from_unsigned_works() {
730 test_try_from_uint_to_int::<Uint256, Int256>("Uint256", "Int256");
731 test_try_from_uint_to_int::<Uint512, Int256>("Uint512", "Int256");
732 }
733
734 #[test]
735 #[allow(deprecated)]
736 fn int256_from_i128() {
737 assert_eq!(Int256::from_i128(123i128), Int256::from_str("123").unwrap());
738
739 assert_eq!(
740 Int256::from_i128(9785746283745i128),
741 Int256::from_str("9785746283745").unwrap()
742 );
743
744 assert_eq!(
745 Int256::from_i128(i128::MAX).to_string(),
746 i128::MAX.to_string()
747 );
748 assert_eq!(
749 Int256::from_i128(i128::MIN).to_string(),
750 i128::MIN.to_string()
751 );
752 }
753
754 #[test]
755 fn int256_implements_display() {
756 let a = Int256::from(12345u32);
757 assert_eq!(format!("Embedded: {a}"), "Embedded: 12345");
758 assert_eq!(a.to_string(), "12345");
759
760 let a = Int256::from(-12345i32);
761 assert_eq!(format!("Embedded: {a}"), "Embedded: -12345");
762 assert_eq!(a.to_string(), "-12345");
763
764 let a = Int256::zero();
765 assert_eq!(format!("Embedded: {a}"), "Embedded: 0");
766 assert_eq!(a.to_string(), "0");
767 }
768
769 #[test]
770 fn int256_display_padding_works() {
771 let a = Int256::from(123u64);
773 assert_eq!(format!("Embedded: {a:05}"), "Embedded: 00123");
774 let a = Int256::from(-123i64);
775 assert_eq!(format!("Embedded: {a:05}"), "Embedded: -0123");
776
777 let a = Int256::from(123u64);
779 assert_eq!(format!("Embedded: {a:02}"), "Embedded: 123");
780 let a = Int256::from(-123i64);
781 assert_eq!(format!("Embedded: {a:02}"), "Embedded: -123");
782 }
783
784 #[test]
785 fn int256_to_be_bytes_works() {
786 assert_eq!(Int256::zero().to_be_bytes(), [0; 32]);
787
788 let mut max = [0xff; 32];
789 max[0] = 0x7f;
790 assert_eq!(Int256::MAX.to_be_bytes(), max);
791
792 let mut one = [0; 32];
793 one[31] = 1;
794 assert_eq!(Int256::from(1u128).to_be_bytes(), one);
795 assert_eq!(
797 Int256::from(240282366920938463463374607431768124608u128).to_be_bytes(),
798 [
799 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 180, 196, 179, 87, 165, 121, 59,
800 133, 246, 117, 221, 191, 255, 254, 172, 192
801 ]
802 );
803 assert_eq!(
804 Int256::from_be_bytes([
805 17, 4, 23, 32, 87, 67, 123, 200, 58, 91, 0, 38, 33, 21, 67, 78, 87, 76, 65, 54,
806 211, 201, 192, 7, 42, 233, 2, 240, 200, 115, 150, 240
807 ])
808 .to_be_bytes(),
809 [
810 17, 4, 23, 32, 87, 67, 123, 200, 58, 91, 0, 38, 33, 21, 67, 78, 87, 76, 65, 54,
811 211, 201, 192, 7, 42, 233, 2, 240, 200, 115, 150, 240
812 ]
813 );
814 }
815
816 #[test]
817 fn int256_to_le_bytes_works() {
818 assert_eq!(Int256::zero().to_le_bytes(), [0; 32]);
819
820 let mut max = [0xff; 32];
821 max[31] = 0x7f;
822 assert_eq!(Int256::MAX.to_le_bytes(), max);
823
824 let mut one = [0; 32];
825 one[0] = 1;
826 assert_eq!(Int256::from(1u128).to_le_bytes(), one);
827 assert_eq!(
829 Int256::from(240282366920938463463374607431768124608u128).to_le_bytes(),
830 [
831 192, 172, 254, 255, 191, 221, 117, 246, 133, 59, 121, 165, 87, 179, 196, 180, 0, 0,
832 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
833 ]
834 );
835 assert_eq!(
836 Int256::from_be_bytes([
837 17, 4, 23, 32, 87, 67, 123, 200, 58, 91, 0, 38, 33, 21, 67, 78, 87, 76, 65, 54,
838 211, 201, 192, 7, 42, 233, 2, 240, 200, 115, 150, 240
839 ])
840 .to_le_bytes(),
841 [
842 240, 150, 115, 200, 240, 2, 233, 42, 7, 192, 201, 211, 54, 65, 76, 87, 78, 67, 21,
843 33, 38, 0, 91, 58, 200, 123, 67, 87, 32, 23, 4, 17
844 ]
845 );
846 }
847
848 #[test]
849 fn int256_is_zero_works() {
850 assert!(Int256::zero().is_zero());
851 assert!(Int256(I256::from(0u32)).is_zero());
852
853 assert!(!Int256::from(1u32).is_zero());
854 assert!(!Int256::from(123u32).is_zero());
855 assert!(!Int256::from(-123i32).is_zero());
856 }
857
858 #[test]
859 fn int256_is_negative_works() {
860 assert!(Int256::MIN.is_negative());
861 assert!(Int256::from(-123i32).is_negative());
862
863 assert!(!Int256::MAX.is_negative());
864 assert!(!Int256::zero().is_negative());
865 assert!(!Int256::from(123u32).is_negative());
866 }
867
868 #[test]
869 fn int256_wrapping_methods() {
870 assert_eq!(
872 Int256::from(2u32).wrapping_add(Int256::from(2u32)),
873 Int256::from(4u32)
874 ); assert_eq!(Int256::MAX.wrapping_add(Int256::from(1u32)), Int256::MIN); assert_eq!(
879 Int256::from(7u32).wrapping_sub(Int256::from(5u32)),
880 Int256::from(2u32)
881 ); assert_eq!(Int256::MIN.wrapping_sub(Int256::from(1u32)), Int256::MAX); assert_eq!(
886 Int256::from(3u32).wrapping_mul(Int256::from(2u32)),
887 Int256::from(6u32)
888 ); assert_eq!(
890 Int256::MAX.wrapping_mul(Int256::from(2u32)),
891 Int256::from(-2i32)
892 ); assert_eq!(Int256::from(2u32).wrapping_pow(3), Int256::from(8u32)); assert_eq!(Int256::MAX.wrapping_pow(2), Int256::from(1u32)); }
898
899 #[test]
900 fn int256_json() {
901 let orig = Int256::from(1234567890987654321u128);
902 let serialized = serde_json::to_vec(&orig).unwrap();
903 assert_eq!(serialized.as_slice(), b"\"1234567890987654321\"");
904 let parsed: Int256 = serde_json::from_slice(&serialized).unwrap();
905 assert_eq!(parsed, orig);
906 }
907
908 #[test]
909 fn int256_compare() {
910 let a = Int256::from(12345u32);
911 let b = Int256::from(23456u32);
912
913 assert!(a < b);
914 assert!(b > a);
915 assert_eq!(a, Int256::from(12345u32));
916 }
917
918 #[test]
919 #[allow(clippy::op_ref)]
920 fn int256_math() {
921 let a = Int256::from(-12345i32);
922 let b = Int256::from(23456u32);
923
924 assert_eq!(a + b, Int256::from(11111u32));
926 assert_eq!(a + &b, Int256::from(11111u32));
927
928 assert_eq!(b - a, Int256::from(35801u32));
930 assert_eq!(b - &a, Int256::from(35801u32));
931
932 let mut c = Int256::from(300000u32);
934 c += b;
935 assert_eq!(c, Int256::from(323456u32));
936 let mut d = Int256::from(300000u32);
937 d += &b;
938 assert_eq!(d, Int256::from(323456u32));
939
940 let mut c = Int256::from(300000u32);
942 c -= b;
943 assert_eq!(c, Int256::from(276544u32));
944 let mut d = Int256::from(300000u32);
945 d -= &b;
946 assert_eq!(d, Int256::from(276544u32));
947
948 assert_eq!(a - b, Int256::from(-35801i32));
950 }
951
952 #[test]
953 #[should_panic]
954 fn int256_add_overflow_panics() {
955 let _ = Int256::MAX + Int256::from(12u32);
956 }
957
958 #[test]
959 #[allow(clippy::op_ref)]
960 fn int256_sub_works() {
961 assert_eq!(Int256::from(2u32) - Int256::from(1u32), Int256::from(1u32));
962 assert_eq!(Int256::from(2u32) - Int256::from(0u32), Int256::from(2u32));
963 assert_eq!(Int256::from(2u32) - Int256::from(2u32), Int256::from(0u32));
964 assert_eq!(Int256::from(2u32) - Int256::from(3u32), Int256::from(-1i32));
965
966 let a = Int256::from(10u32);
968 let b = Int256::from(3u32);
969 let expected = Int256::from(7u32);
970 assert_eq!(a - b, expected);
971 assert_eq!(a - &b, expected);
972 assert_eq!(&a - b, expected);
973 assert_eq!(&a - &b, expected);
974 }
975
976 #[test]
977 #[should_panic]
978 fn int256_sub_overflow_panics() {
979 let _ = Int256::MIN + Int256::one() - Int256::from(2u32);
980 }
981
982 #[test]
983 fn int256_sub_assign_works() {
984 let mut a = Int256::from(14u32);
985 a -= Int256::from(2u32);
986 assert_eq!(a, Int256::from(12u32));
987
988 let mut a = Int256::from(10u32);
990 let b = Int256::from(3u32);
991 let expected = Int256::from(7u32);
992 a -= &b;
993 assert_eq!(a, expected);
994 }
995
996 #[test]
997 #[allow(clippy::op_ref)]
998 fn int256_mul_works() {
999 assert_eq!(Int256::from(2u32) * Int256::from(3u32), Int256::from(6u32));
1000 assert_eq!(Int256::from(2u32) * Int256::zero(), Int256::zero());
1001
1002 let a = Int256::from(11u32);
1004 let b = Int256::from(3u32);
1005 let expected = Int256::from(33u32);
1006 assert_eq!(a * b, expected);
1007 assert_eq!(a * &b, expected);
1008 assert_eq!(&a * b, expected);
1009 assert_eq!(&a * &b, expected);
1010 }
1011
1012 #[test]
1013 fn int256_mul_assign_works() {
1014 let mut a = Int256::from(14u32);
1015 a *= Int256::from(2u32);
1016 assert_eq!(a, Int256::from(28u32));
1017
1018 let mut a = Int256::from(10u32);
1020 let b = Int256::from(3u32);
1021 a *= &b;
1022 assert_eq!(a, Int256::from(30u32));
1023 }
1024
1025 #[test]
1026 fn int256_pow_works() {
1027 assert_eq!(Int256::from(2u32).pow(2), Int256::from(4u32));
1028 assert_eq!(Int256::from(2u32).pow(10), Int256::from(1024u32));
1029 }
1030
1031 #[test]
1032 #[should_panic]
1033 fn int256_pow_overflow_panics() {
1034 _ = Int256::MAX.pow(2u32);
1035 }
1036
1037 #[test]
1038 fn int256_checked_multiply_ratio_works() {
1039 let base = Int256::new(500);
1040
1041 assert_eq!(base.checked_multiply_ratio(1i128, 1i128).unwrap(), base);
1043 assert_eq!(base.checked_multiply_ratio(3i128, 3i128).unwrap(), base);
1044 assert_eq!(
1045 base.checked_multiply_ratio(654321i128, 654321i128).unwrap(),
1046 base
1047 );
1048 assert_eq!(
1049 base.checked_multiply_ratio(i128::MAX, i128::MAX).unwrap(),
1050 base
1051 );
1052
1053 assert_eq!(
1055 base.checked_multiply_ratio(3i128, 2i128).unwrap(),
1056 Int256::new(750)
1057 );
1058 assert_eq!(
1059 base.checked_multiply_ratio(333333i128, 222222i128).unwrap(),
1060 Int256::new(750)
1061 );
1062
1063 assert_eq!(
1065 base.checked_multiply_ratio(2i128, 3i128).unwrap(),
1066 Int256::new(333)
1067 );
1068 assert_eq!(
1069 base.checked_multiply_ratio(222222i128, 333333i128).unwrap(),
1070 Int256::new(333)
1071 );
1072
1073 assert_eq!(
1075 base.checked_multiply_ratio(5i128, 6i128).unwrap(),
1076 Int256::new(416)
1077 );
1078 assert_eq!(
1079 base.checked_multiply_ratio(100i128, 120i128).unwrap(),
1080 Int256::new(416)
1081 );
1082 }
1083
1084 #[test]
1085 fn int256_checked_multiply_ratio_does_not_panic() {
1086 assert_eq!(
1087 Int256::new(500i128).checked_multiply_ratio(1i128, 0i128),
1088 Err(CheckedMultiplyRatioError::DivideByZero),
1089 );
1090 assert_eq!(
1091 Int256::MAX.checked_multiply_ratio(Int256::MAX, 1i128),
1092 Err(CheckedMultiplyRatioError::Overflow),
1093 );
1094 }
1095
1096 #[test]
1097 fn int256_shr_works() {
1098 let original = Int256::from_be_bytes([
1099 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
1100 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 4u8, 2u8,
1101 ]);
1102
1103 let shifted = Int256::from_be_bytes([
1104 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
1105 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 128u8, 1u8, 0u8,
1106 ]);
1107
1108 assert_eq!(original >> 2u32, shifted);
1109 }
1110
1111 #[test]
1112 #[should_panic]
1113 fn int256_shr_overflow_panics() {
1114 let _ = Int256::from(1u32) >> 256u32;
1115 }
1116
1117 #[test]
1118 fn sum_works() {
1119 let nums = vec![
1120 Int256::from(17u32),
1121 Int256::from(123u32),
1122 Int256::from(540u32),
1123 Int256::from(82u32),
1124 ];
1125 let expected = Int256::from(762u32);
1126
1127 let sum_as_ref: Int256 = nums.iter().sum();
1128 assert_eq!(expected, sum_as_ref);
1129
1130 let sum_as_owned: Int256 = nums.into_iter().sum();
1131 assert_eq!(expected, sum_as_owned);
1132 }
1133
1134 #[test]
1135 fn int256_methods() {
1136 assert!(matches!(
1138 Int256::MAX.checked_add(Int256::from(1u32)),
1139 Err(OverflowError { .. })
1140 ));
1141 assert_eq!(
1142 Int256::from(1u32).checked_add(Int256::from(1u32)),
1143 Ok(Int256::from(2u32)),
1144 );
1145 assert!(matches!(
1146 Int256::MIN.checked_sub(Int256::from(1u32)),
1147 Err(OverflowError { .. })
1148 ));
1149 assert_eq!(
1150 Int256::from(2u32).checked_sub(Int256::from(1u32)),
1151 Ok(Int256::from(1u32)),
1152 );
1153 assert!(matches!(
1154 Int256::MAX.checked_mul(Int256::from(2u32)),
1155 Err(OverflowError { .. })
1156 ));
1157 assert_eq!(
1158 Int256::from(2u32).checked_mul(Int256::from(2u32)),
1159 Ok(Int256::from(4u32)),
1160 );
1161 assert!(matches!(
1162 Int256::MAX.checked_pow(2u32),
1163 Err(OverflowError { .. })
1164 ));
1165 assert_eq!(Int256::from(2u32).checked_pow(3u32), Ok(Int256::from(8u32)),);
1166 assert_eq!(
1167 Int256::MAX.checked_div(Int256::from(0u32)),
1168 Err(DivisionError::DivideByZero)
1169 );
1170 assert_eq!(
1171 Int256::from(6u32).checked_div(Int256::from(2u32)),
1172 Ok(Int256::from(3u32)),
1173 );
1174 assert_eq!(
1175 Int256::MAX.checked_div_euclid(Int256::from(0u32)),
1176 Err(DivisionError::DivideByZero)
1177 );
1178 assert_eq!(
1179 Int256::from(6u32).checked_div_euclid(Int256::from(2u32)),
1180 Ok(Int256::from(3u32)),
1181 );
1182 assert_eq!(
1183 Int256::from(7u32).checked_div_euclid(Int256::from(2u32)),
1184 Ok(Int256::from(3u32)),
1185 );
1186 assert!(matches!(
1187 Int256::MAX.checked_rem(Int256::from(0u32)),
1188 Err(DivideByZeroError { .. })
1189 ));
1190 assert_eq!(
1192 Int256::from(-12i32).checked_div(Int256::from(10i32)),
1193 Ok(Int256::from(-1i32)),
1194 );
1195 assert_eq!(
1196 Int256::from(-2i32).checked_pow(3u32),
1197 Ok(Int256::from(-8i32)),
1198 );
1199 assert_eq!(
1200 Int256::from(-6i32).checked_mul(Int256::from(-7i32)),
1201 Ok(Int256::from(42i32)),
1202 );
1203 assert_eq!(
1204 Int256::from(-2i32).checked_add(Int256::from(3i32)),
1205 Ok(Int256::from(1i32)),
1206 );
1207 assert_eq!(
1208 Int256::from(-1i32).checked_div_euclid(Int256::from(-2i32)),
1209 Ok(Int256::from(1u32)),
1210 );
1211
1212 assert_eq!(Int256::MAX.saturating_add(Int256::from(1u32)), Int256::MAX);
1214 assert_eq!(Int256::MIN.saturating_sub(Int256::from(1u32)), Int256::MIN);
1215 assert_eq!(Int256::MAX.saturating_mul(Int256::from(2u32)), Int256::MAX);
1216 assert_eq!(Int256::from(4u32).saturating_pow(2u32), Int256::from(16u32));
1217 assert_eq!(Int256::MAX.saturating_pow(2u32), Int256::MAX);
1218 }
1219
1220 #[test]
1221 #[allow(clippy::op_ref)]
1222 fn int256_implements_rem() {
1223 let a = Int256::from(10u32);
1224 assert_eq!(a % Int256::from(10u32), Int256::zero());
1225 assert_eq!(a % Int256::from(2u32), Int256::zero());
1226 assert_eq!(a % Int256::from(1u32), Int256::zero());
1227 assert_eq!(a % Int256::from(3u32), Int256::from(1u32));
1228 assert_eq!(a % Int256::from(4u32), Int256::from(2u32));
1229
1230 assert_eq!(
1231 Int256::from(-12i32) % Int256::from(10i32),
1232 Int256::from(-2i32)
1233 );
1234 assert_eq!(
1235 Int256::from(12i32) % Int256::from(-10i32),
1236 Int256::from(2i32)
1237 );
1238 assert_eq!(
1239 Int256::from(-12i32) % Int256::from(-10i32),
1240 Int256::from(-2i32)
1241 );
1242
1243 let a = Int256::from(10u32);
1245 let b = Int256::from(3u32);
1246 let expected = Int256::from(1u32);
1247 assert_eq!(a % b, expected);
1248 assert_eq!(a % &b, expected);
1249 assert_eq!(&a % b, expected);
1250 assert_eq!(&a % &b, expected);
1251 }
1252
1253 #[test]
1254 #[should_panic(expected = "divisor of zero")]
1255 fn int256_rem_panics_for_zero() {
1256 let _ = Int256::from(10u32) % Int256::zero();
1257 }
1258
1259 #[test]
1260 fn int256_rem_assign_works() {
1261 let mut a = Int256::from(30u32);
1262 a %= Int256::from(4u32);
1263 assert_eq!(a, Int256::from(2u32));
1264
1265 let mut a = Int256::from(25u32);
1267 let b = Int256::from(6u32);
1268 a %= &b;
1269 assert_eq!(a, Int256::from(1u32));
1270 }
1271
1272 #[test]
1273 fn int256_shr() {
1274 let x: Int256 = 0x8000_0000_0000_0000_0000_0000_0000_0000u128.into();
1275 assert_eq!(x >> 0, x); assert_eq!(
1277 x >> 1,
1278 Int256::from(0x4000_0000_0000_0000_0000_0000_0000_0000u128)
1279 );
1280 assert_eq!(
1281 x >> 4,
1282 Int256::from(0x0800_0000_0000_0000_0000_0000_0000_0000u128)
1283 );
1284 assert_eq!(
1286 Int256::MIN >> (core::mem::size_of::<Int256>() as u32 * 8 - 1),
1287 -Int256::one()
1288 );
1289 }
1290
1291 #[test]
1292 fn int256_shl() {
1293 let x: Int256 = 0x0800_0000_0000_0000_0000_0000_0000_0000u128.into();
1294 assert_eq!(x << 0, x); assert_eq!(
1296 x << 1,
1297 Int256::from(0x1000_0000_0000_0000_0000_0000_0000_0000u128)
1298 );
1299 assert_eq!(
1300 x << 4,
1301 Int256::from(0x8000_0000_0000_0000_0000_0000_0000_0000u128)
1302 );
1303 assert_eq!(
1305 Int256::one() << (core::mem::size_of::<Int256>() as u32 * 8 - 1),
1306 Int256::MIN
1307 );
1308 }
1309
1310 #[test]
1311 fn int256_abs_diff_works() {
1312 let a = Int256::from(42u32);
1313 let b = Int256::from(5u32);
1314 let expected = Uint256::from(37u32);
1315 assert_eq!(a.abs_diff(b), expected);
1316 assert_eq!(b.abs_diff(a), expected);
1317
1318 let c = Int256::from(-5i32);
1319 assert_eq!(b.abs_diff(c), Uint256::from(10u32));
1320 assert_eq!(c.abs_diff(b), Uint256::from(10u32));
1321 }
1322
1323 #[test]
1324 fn int256_abs_works() {
1325 let a = Int256::from(42i32);
1326 assert_eq!(a.abs(), a);
1327
1328 let b = Int256::from(-42i32);
1329 assert_eq!(b.abs(), a);
1330
1331 assert_eq!(Int256::zero().abs(), Int256::zero());
1332 assert_eq!((Int256::MIN + Int256::one()).abs(), Int256::MAX);
1333 }
1334
1335 #[test]
1336 fn int256_unsigned_abs_works() {
1337 assert_eq!(Int256::zero().unsigned_abs(), Uint256::zero());
1338 assert_eq!(Int256::one().unsigned_abs(), Uint256::one());
1339 assert_eq!(
1340 Int256::MIN.unsigned_abs(),
1341 Uint256::from_be_bytes(Int256::MAX.to_be_bytes()) + Uint256::one()
1342 );
1343
1344 let v = Int256::from(-42i32);
1345 assert_eq!(v.unsigned_abs(), v.abs_diff(Int256::zero()));
1346 }
1347
1348 #[test]
1349 #[should_panic = "attempt to calculate absolute value with overflow"]
1350 fn int256_abs_min_panics() {
1351 _ = Int256::MIN.abs();
1352 }
1353
1354 #[test]
1355 #[should_panic = "attempt to negate with overflow"]
1356 fn int256_neg_min_panics() {
1357 _ = -Int256::MIN;
1358 }
1359
1360 #[test]
1361 fn int256_partial_eq() {
1362 let test_cases = [(1, 1, true), (42, 42, true), (42, 24, false), (0, 0, true)]
1363 .into_iter()
1364 .map(|(lhs, rhs, expected): (u64, u64, bool)| {
1365 (Int256::from(lhs), Int256::from(rhs), expected)
1366 });
1367
1368 #[allow(clippy::op_ref)]
1369 for (lhs, rhs, expected) in test_cases {
1370 assert_eq!(lhs == rhs, expected);
1371 assert_eq!(&lhs == rhs, expected);
1372 assert_eq!(lhs == &rhs, expected);
1373 assert_eq!(&lhs == &rhs, expected);
1374 }
1375 }
1376}