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