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