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