1use crate::arith::derive_arith;
19use crate::bigint::div::div_rem;
20use num_bigint::BigInt;
21use num_traits::{
22 Bounded, CheckedAdd, CheckedDiv, CheckedMul, CheckedNeg, CheckedRem, CheckedShl, CheckedShr,
23 CheckedSub, ConstOne, ConstZero, FromPrimitive, MulAdd, MulAddAssign, Num, One, SaturatingAdd,
24 SaturatingMul, SaturatingSub, Signed, ToPrimitive, WrappingAdd, WrappingMul, WrappingNeg,
25 WrappingShl, WrappingShr, WrappingSub, Zero, cast::AsPrimitive,
26};
27use std::cmp::Ordering;
28use std::num::ParseIntError;
29use std::ops::{BitAnd, BitOr, BitXor, Neg, Not, Shl, Shr};
30use std::str::FromStr;
31
32mod div;
33
34#[derive(Debug)]
36pub struct ParseI256Error {}
37
38impl From<ParseIntError> for ParseI256Error {
39 fn from(_: ParseIntError) -> Self {
40 Self {}
41 }
42}
43
44impl std::fmt::Display for ParseI256Error {
45 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
46 write!(f, "Failed to parse as i256")
47 }
48}
49impl std::error::Error for ParseI256Error {}
50
51enum DivRemError {
53 DivideByZero,
55 DivideOverflow,
57}
58
59#[derive(Copy, Clone, Default, Eq, PartialEq, Hash)]
61#[repr(C)]
62pub struct i256 {
63 low: u128,
64 high: i128,
65}
66
67impl std::fmt::Debug for i256 {
68 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
69 write!(f, "{self}")
70 }
71}
72
73impl std::fmt::Display for i256 {
74 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
75 write!(f, "{}", BigInt::from_signed_bytes_le(&self.to_le_bytes()))
76 }
77}
78
79impl FromStr for i256 {
80 type Err = ParseI256Error;
81
82 fn from_str(s: &str) -> Result<Self, Self::Err> {
83 if s.len() <= 38 {
85 return Ok(Self::from_i128(i128::from_str(s)?));
86 }
87
88 let (negative, s) = match s.as_bytes()[0] {
89 b'-' => (true, &s[1..]),
90 b'+' => (false, &s[1..]),
91 _ => (false, s),
92 };
93
94 let s = s.trim_start_matches('0');
96 if s.is_empty() {
97 return Ok(i256::ZERO);
98 }
99
100 if !s.as_bytes()[0].is_ascii_digit() {
101 return Err(ParseI256Error {});
103 }
104
105 parse_impl(s, negative)
106 }
107}
108
109impl From<i8> for i256 {
110 fn from(value: i8) -> Self {
111 Self::from_i128(value.into())
112 }
113}
114
115impl From<i16> for i256 {
116 fn from(value: i16) -> Self {
117 Self::from_i128(value.into())
118 }
119}
120
121impl From<i32> for i256 {
122 fn from(value: i32) -> Self {
123 Self::from_i128(value.into())
124 }
125}
126
127impl From<i64> for i256 {
128 fn from(value: i64) -> Self {
129 Self::from_i128(value.into())
130 }
131}
132
133impl From<i128> for i256 {
134 fn from(value: i128) -> Self {
135 Self::from_i128(value)
136 }
137}
138
139fn parse_impl(s: &str, negative: bool) -> Result<i256, ParseI256Error> {
141 if s.len() <= 38 {
142 let low = i128::from_str(s)?;
143 return Ok(match negative {
144 true => i256::from_parts(low.neg() as _, -1),
145 false => i256::from_parts(low as _, 0),
146 });
147 }
148
149 let split = s.len() - 38;
150 if !s.as_bytes()[split].is_ascii_digit() {
151 return Err(ParseI256Error {});
153 }
154 let (hs, ls) = s.split_at(split);
155
156 let mut low = i128::from_str(ls)?;
157 let high = parse_impl(hs, negative)?;
158
159 if negative {
160 low = -low;
161 }
162
163 let low = i256::from_i128(low);
164
165 high.checked_mul(i256::from_i128(10_i128.pow(38)))
166 .and_then(|high| high.checked_add(low))
167 .ok_or(ParseI256Error {})
168}
169
170impl PartialOrd for i256 {
171 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
172 Some(self.cmp(other))
173 }
174}
175
176impl Ord for i256 {
177 fn cmp(&self, other: &Self) -> Ordering {
178 self.high.cmp(&other.high).then(self.low.cmp(&other.low))
181 }
182}
183
184impl i256 {
185 pub const ZERO: Self = i256 { low: 0, high: 0 };
187
188 pub const ONE: Self = i256 { low: 1, high: 0 };
190
191 pub const MINUS_ONE: Self = i256 {
193 low: u128::MAX,
194 high: -1,
195 };
196
197 pub const MAX: Self = i256 {
199 low: u128::MAX,
200 high: i128::MAX,
201 };
202
203 pub const MIN: Self = i256 {
205 low: u128::MIN,
206 high: i128::MIN,
207 };
208
209 #[inline]
211 pub const fn from_le_bytes(b: [u8; 32]) -> Self {
212 let (low, high) = split_array(b);
213 Self {
214 high: i128::from_le_bytes(high),
215 low: u128::from_le_bytes(low),
216 }
217 }
218
219 #[inline]
221 pub const fn from_be_bytes(b: [u8; 32]) -> Self {
222 let (high, low) = split_array(b);
223 Self {
224 high: i128::from_be_bytes(high),
225 low: u128::from_be_bytes(low),
226 }
227 }
228
229 pub const fn from_i128(v: i128) -> Self {
231 Self::from_parts(v as u128, v >> 127)
232 }
233
234 #[inline]
236 pub fn from_string(value_str: &str) -> Option<Self> {
237 value_str.parse().ok()
238 }
239
240 pub fn from_f64(v: f64) -> Option<Self> {
243 let (integer, overflow) = i256::from_bigint_with_overflow(BigInt::from_f64(v)?);
244 if overflow { None } else { Some(integer) }
245 }
246
247 #[inline]
249 pub const fn from_parts(low: u128, high: i128) -> Self {
250 Self { low, high }
251 }
252
253 pub const fn to_parts(self) -> (u128, i128) {
255 (self.low, self.high)
256 }
257
258 pub const fn to_i128(self) -> Option<i128> {
261 let as_i128 = self.low as i128;
262
263 let high_negative = self.high < 0;
264 let low_negative = as_i128 < 0;
265 let high_valid = self.high == -1 || self.high == 0;
266
267 if (high_negative == low_negative) && high_valid {
268 Some(self.low as i128)
269 } else {
270 None
271 }
272 }
273
274 pub const fn as_i128(self) -> i128 {
276 self.low as i128
277 }
278
279 #[inline]
281 pub const fn to_le_bytes(self) -> [u8; 32] {
282 let low = self.low.to_le_bytes();
283 let high = self.high.to_le_bytes();
284 let mut t = [0; 32];
285 let mut i = 0;
286 while i != 16 {
287 t[i] = low[i];
288 t[i + 16] = high[i];
289 i += 1;
290 }
291 t
292 }
293
294 #[inline]
296 pub const fn to_be_bytes(self) -> [u8; 32] {
297 let low = self.low.to_be_bytes();
298 let high = self.high.to_be_bytes();
299 let mut t = [0; 32];
300 let mut i = 0;
301 while i != 16 {
302 t[i] = high[i];
303 t[i + 16] = low[i];
304 i += 1;
305 }
306 t
307 }
308
309 fn from_bigint_with_overflow(v: BigInt) -> (Self, bool) {
312 let v_bytes = v.to_signed_bytes_le();
313 match v_bytes.len().cmp(&32) {
314 Ordering::Less => {
315 let mut bytes = if num_traits::Signed::is_negative(&v) {
316 [255_u8; 32]
317 } else {
318 [0; 32]
319 };
320 bytes[0..v_bytes.len()].copy_from_slice(&v_bytes[..v_bytes.len()]);
321 (Self::from_le_bytes(bytes), false)
322 }
323 Ordering::Equal => (Self::from_le_bytes(v_bytes.try_into().unwrap()), false),
324 Ordering::Greater => (Self::from_le_bytes(v_bytes[..32].try_into().unwrap()), true),
325 }
326 }
327
328 #[inline]
330 pub const fn wrapping_abs(self) -> Self {
331 let sa = self.high >> 127;
333 let sa = Self::from_parts(sa as u128, sa);
334
335 Self::from_parts(self.low ^ sa.low, self.high ^ sa.high).wrapping_sub(sa)
337 }
338
339 #[inline]
341 pub const fn checked_abs(self) -> Option<Self> {
342 if !self.is_eq(Self::MIN) {
343 Some(self.wrapping_abs())
344 } else {
345 None
346 }
347 }
348
349 #[inline]
351 pub const fn wrapping_neg(self) -> Self {
352 Self::from_parts(!self.low, !self.high).wrapping_add(i256::ONE)
353 }
354
355 #[inline]
357 pub const fn checked_neg(self) -> Option<Self> {
358 if !self.is_eq(Self::MIN) {
359 Some(self.wrapping_neg())
360 } else {
361 None
362 }
363 }
364
365 #[inline]
367 pub const fn wrapping_add(self, other: Self) -> Self {
368 let (low, carry) = self.low.overflowing_add(other.low);
369 let high = self.high.wrapping_add(other.high).wrapping_add(carry as _);
370 Self { low, high }
371 }
372
373 #[inline]
375 pub const fn checked_add(self, other: Self) -> Option<Self> {
376 let (r, overflow) = self.overflowing_add(other);
377
378 if overflow { None } else { Some(r) }
379 }
380
381 #[inline]
383 pub const fn wrapping_sub(self, other: Self) -> Self {
384 let (low, carry) = self.low.overflowing_sub(other.low);
385 let high = self.high.wrapping_sub(other.high).wrapping_sub(carry as _);
386 Self { low, high }
387 }
388
389 #[inline]
391 pub const fn checked_sub(self, other: Self) -> Option<Self> {
392 let (r, overflow) = self.overflowing_sub(other);
393
394 if overflow { None } else { Some(r) }
395 }
396
397 #[inline]
399 pub const fn wrapping_mul(self, other: Self) -> Self {
400 let (low, high) = mulx(self.low, other.low);
401
402 let hl = self.high.wrapping_mul(other.low as i128);
404 let lh = (self.low as i128).wrapping_mul(other.high);
405
406 Self {
407 low,
408 high: (high as i128).wrapping_add(hl).wrapping_add(lh),
409 }
410 }
411
412 const fn is_eq(&self, other: Self) -> bool {
414 (self.high == other.high) && (self.low == other.low)
415 }
416
417 #[inline]
419 pub const fn checked_mul(self, other: Self) -> Option<Self> {
420 if self.is_eq(Self::ZERO) || other.is_eq(Self::ZERO) {
421 return Some(i256::ZERO);
422 }
423
424 let l_sa = self.high >> 127;
426 let r_sa = other.high >> 127;
427 let out_sa = (l_sa ^ r_sa) as u128;
428
429 let l_abs = self.wrapping_abs();
431 let r_abs = other.wrapping_abs();
432
433 if l_abs.high != 0 && r_abs.high != 0 {
435 return None;
436 }
437
438 let (low, high) = mulx(l_abs.low, r_abs.low);
440
441 let Some(hl) = (l_abs.high as u128).checked_mul(r_abs.low) else {
443 return None;
444 };
445 let Some(lh) = l_abs.low.checked_mul(r_abs.high as u128) else {
446 return None;
447 };
448
449 let Some(high) = high.checked_add(hl) else {
450 return None;
451 };
452 let Some(high) = high.checked_add(lh) else {
453 return None;
454 };
455
456 let (low, c) = (low ^ out_sa).overflowing_sub(out_sa);
458 let high = (high ^ out_sa).wrapping_sub(out_sa).wrapping_sub(c as u128) as i128;
459
460 if high.is_negative() == (self.is_negative() ^ other.is_negative()) {
462 Some(Self { low, high })
463 } else {
464 None
465 }
466 }
467
468 #[inline]
471 fn div_rem(self, other: Self) -> Result<(Self, Self), DivRemError> {
472 if other == Self::ZERO {
473 return Err(DivRemError::DivideByZero);
474 }
475 if other == Self::MINUS_ONE && self == Self::MIN {
476 return Err(DivRemError::DivideOverflow);
477 }
478
479 let a = self.wrapping_abs();
480 let b = other.wrapping_abs();
481
482 let (div, rem) = div_rem(&a.as_digits(), &b.as_digits());
483 let div = Self::from_digits(div);
484 let rem = Self::from_digits(rem);
485
486 Ok((
487 if self.is_negative() == other.is_negative() {
488 div
489 } else {
490 div.wrapping_neg()
491 },
492 if self.is_negative() {
493 rem.wrapping_neg()
494 } else {
495 rem
496 },
497 ))
498 }
499
500 fn as_digits(self) -> [u64; 4] {
502 [
503 self.low as u64,
504 (self.low >> 64) as u64,
505 self.high as u64,
506 (self.high as u128 >> 64) as u64,
507 ]
508 }
509
510 fn from_digits(digits: [u64; 4]) -> Self {
512 Self::from_parts(
513 digits[0] as u128 | ((digits[1] as u128) << 64),
514 digits[2] as i128 | ((digits[3] as i128) << 64),
515 )
516 }
517
518 #[inline]
524 pub fn wrapping_div(self, other: Self) -> Self {
525 match self.div_rem(other) {
526 Ok((v, _)) => v,
527 Err(DivRemError::DivideByZero) => panic!("attempt to divide by zero"),
528 Err(_) => Self::MIN,
529 }
530 }
531
532 #[inline]
534 pub fn checked_div(self, other: Self) -> Option<Self> {
535 self.div_rem(other).map(|(v, _)| v).ok()
536 }
537
538 #[inline]
544 pub fn wrapping_rem(self, other: Self) -> Self {
545 match self.div_rem(other) {
546 Ok((_, v)) => v,
547 Err(DivRemError::DivideByZero) => panic!("attempt to divide by zero"),
548 Err(_) => Self::ZERO,
549 }
550 }
551
552 #[inline]
554 pub fn checked_rem(self, other: Self) -> Option<Self> {
555 self.div_rem(other).map(|(_, v)| v).ok()
556 }
557
558 #[inline]
560 pub const fn checked_pow(self, mut exp: u32) -> Option<Self> {
561 if exp == 0 {
562 return Some(i256::from_i128(1));
563 }
564
565 let mut base = self;
566 let mut acc: Self = i256::from_i128(1);
567
568 while exp > 1 {
569 if (exp & 1) == 1 {
570 let Some(next) = acc.checked_mul(base) else {
571 return None;
572 };
573 acc = next;
574 }
575 exp /= 2;
576 let Some(next) = base.checked_mul(base) else {
577 return None;
578 };
579 base = next;
580 }
581 acc.checked_mul(base)
586 }
587
588 #[inline]
590 pub const fn wrapping_pow(self, mut exp: u32) -> Self {
591 if exp == 0 {
592 return i256::from_i128(1);
593 }
594
595 let mut base = self;
596 let mut acc: Self = i256::from_i128(1);
597
598 while exp > 1 {
599 if (exp & 1) == 1 {
600 acc = acc.wrapping_mul(base);
601 }
602 exp /= 2;
603 base = base.wrapping_mul(base);
604 }
605
606 acc.wrapping_mul(base)
611 }
612
613 pub const fn signum(self) -> Self {
619 if self.is_positive() {
620 i256::ONE
621 } else if self.is_negative() {
622 i256::MINUS_ONE
623 } else {
624 i256::ZERO
625 }
626 }
627
628 #[inline]
630 pub const fn is_negative(self) -> bool {
631 self.high.is_negative()
632 }
633
634 pub const fn is_positive(self) -> bool {
636 self.high.is_positive() || self.high == 0 && self.low != 0
637 }
638
639 pub const fn leading_zeros(&self) -> u32 {
641 match self.high {
642 0 => u128::BITS + self.low.leading_zeros(),
643 _ => self.high.leading_zeros(),
644 }
645 }
646
647 pub const fn trailing_zeros(&self) -> u32 {
649 match self.low {
650 0 => u128::BITS + self.high.trailing_zeros(),
651 _ => self.low.trailing_zeros(),
652 }
653 }
654
655 fn redundant_leading_sign_bits_i256(n: i256) -> u8 {
656 let mask = n >> 255; ((n ^ mask).leading_zeros() - 1) as u8 }
659
660 fn i256_to_f64(input: i256) -> f64 {
661 let k = i256::redundant_leading_sign_bits_i256(input);
662 let n = input << k; let n = (n.high >> 64) as i64; (n as f64) * f64::powi(2.0, 192 - (k as i32)) }
666
667 #[inline]
670 pub fn checked_ilog(self, base: i256) -> Option<u32> {
671 if base == Self::from(10) {
672 return self.checked_ilog10();
674 }
675
676 if self <= Self::ZERO {
677 return None;
678 }
679 if base <= Self::ONE {
680 return None;
681 }
682 if self < base {
683 return Some(0);
684 }
685
686 let mut val = 1;
687 let mut base_exp = base;
688
689 let boundary = self.checked_div(base)?;
690 while base_exp <= boundary {
691 val += 1;
692 base_exp = base_exp.checked_mul(base)?;
693 }
694 Some(val)
695 }
696
697 #[inline]
703 pub fn ilog(self, base: i256) -> u32 {
704 self.checked_ilog(base)
705 .unwrap_or_else(|| panic!("ilog overflow with {self} and base {base}"))
706 }
707
708 #[inline]
711 pub fn checked_ilog10(self) -> Option<u32> {
712 if self <= Self::ZERO {
713 return None;
714 }
715 if self < Self::from(10) {
716 return Some(0);
717 }
718
719 const POW10_32: i256 = i256::from_i128(100_000_000_000_000_000_000_000_000_000_000);
721
722 const POW10_64: i256 = i256::from_parts(
724 146_510_663_073_550_942_663_504_491_129_887_260_672,
725 29_387_358_770_557_187_699_218_413,
726 );
727
728 if self >= POW10_64 {
731 let value = self.checked_div(POW10_64)?;
732 debug_assert!(value.high == 0);
736 Some(64 + value.low.checked_ilog10()?)
737 } else if self >= POW10_32 {
738 let value = self.checked_div(POW10_32)?;
739 debug_assert!(value.high == 0);
743 Some(32 + value.low.checked_ilog10()?)
744 } else {
745 self.low.checked_ilog10()
747 }
748 }
749
750 #[inline]
756 pub fn ilog10(self) -> u32 {
757 self.checked_ilog10()
758 .unwrap_or_else(|| panic!("ilog10 overflow with {self}"))
759 }
760
761 #[inline]
764 pub fn checked_ilog2(self) -> Option<u32> {
765 self.checked_ilog(i256::from(2))
766 }
767
768 #[inline]
774 pub fn ilog2(self) -> u32 {
775 self.checked_ilog2()
776 .unwrap_or_else(|| panic!("ilog2 overflow with {self}"))
777 }
778
779 #[inline]
784 pub const fn overflowing_add(self, rhs: Self) -> (Self, bool) {
785 let (low, carry) = self.low.overflowing_add(rhs.low);
787
788 let high = (self.high as u128)
790 .wrapping_add(rhs.high as u128)
791 .wrapping_add(carry as u128) as i128;
792
793 let result = Self { low, high };
794
795 let overflow = (self.high < 0) == (rhs.high < 0) && (high < 0) != (self.high < 0);
799
800 (result, overflow)
801 }
802
803 #[inline]
808 pub const fn overflowing_sub(self, rhs: Self) -> (Self, bool) {
809 let (low, borrow) = self.low.overflowing_sub(rhs.low);
811
812 let high = (self.high as u128)
814 .wrapping_sub(rhs.high as u128)
815 .wrapping_sub(borrow as u128) as i128;
816
817 let result = Self { low, high };
818
819 let overflow = (self.high < 0) != (rhs.high < 0) && (high < 0) != (self.high < 0);
823
824 (result, overflow)
825 }
826}
827
828const fn split_array<const N: usize, const M: usize>(vals: [u8; N]) -> ([u8; M], [u8; M]) {
831 let mut a = [0; M];
832 let mut b = [0; M];
833 let mut i = 0;
834 while i != M {
835 a[i] = vals[i];
836 b[i] = vals[i + M];
837 i += 1;
838 }
839 (a, b)
840}
841
842#[inline]
848const fn mulx(a: u128, b: u128) -> (u128, u128) {
849 const fn split(a: u128) -> (u128, u128) {
850 (a & (u64::MAX as u128), a >> 64)
851 }
852
853 const MASK: u128 = u64::MAX as _;
854
855 let (a_low, a_high) = split(a);
856 let (b_low, b_high) = split(b);
857
858 let (mut low, mut carry) = split(a_low * b_low);
860 carry += a_high * b_low;
861
862 low += carry << 64;
864 let mut high = carry >> 64;
865
866 carry = low >> 64;
868 low &= MASK;
869
870 carry += b_high * a_low;
872
873 low += carry << 64;
875 high += carry >> 64;
876
877 high += a_high * b_high;
879
880 (low, high)
881}
882
883derive_arith!(
884 i256,
885 Add,
886 AddAssign,
887 add,
888 add_assign,
889 wrapping_add,
890 checked_add
891);
892derive_arith!(
893 i256,
894 Sub,
895 SubAssign,
896 sub,
897 sub_assign,
898 wrapping_sub,
899 checked_sub
900);
901derive_arith!(
902 i256,
903 Mul,
904 MulAssign,
905 mul,
906 mul_assign,
907 wrapping_mul,
908 checked_mul
909);
910derive_arith!(
911 i256,
912 Div,
913 DivAssign,
914 div,
915 div_assign,
916 wrapping_div,
917 checked_div
918);
919derive_arith!(
920 i256,
921 Rem,
922 RemAssign,
923 rem,
924 rem_assign,
925 wrapping_rem,
926 checked_rem
927);
928
929impl Neg for i256 {
930 type Output = i256;
931
932 #[cfg(debug_assertions)]
933 fn neg(self) -> Self::Output {
934 self.checked_neg().expect("i256 overflow")
935 }
936
937 #[cfg(not(debug_assertions))]
938 fn neg(self) -> Self::Output {
939 self.wrapping_neg()
940 }
941}
942
943impl BitAnd for i256 {
944 type Output = i256;
945
946 #[inline]
947 fn bitand(self, rhs: Self) -> Self::Output {
948 Self {
949 low: self.low & rhs.low,
950 high: self.high & rhs.high,
951 }
952 }
953}
954
955impl BitOr for i256 {
956 type Output = i256;
957
958 #[inline]
959 fn bitor(self, rhs: Self) -> Self::Output {
960 Self {
961 low: self.low | rhs.low,
962 high: self.high | rhs.high,
963 }
964 }
965}
966
967impl BitXor for i256 {
968 type Output = i256;
969
970 #[inline]
971 fn bitxor(self, rhs: Self) -> Self::Output {
972 Self {
973 low: self.low ^ rhs.low,
974 high: self.high ^ rhs.high,
975 }
976 }
977}
978
979impl Shl<u8> for i256 {
980 type Output = i256;
981
982 #[inline]
983 fn shl(self, rhs: u8) -> Self::Output {
984 if rhs == 0 {
985 self
986 } else if rhs < 128 {
987 Self {
988 high: (self.high << rhs) | (self.low >> (128 - rhs)) as i128,
989 low: self.low << rhs,
990 }
991 } else {
992 Self {
993 high: (self.low << (rhs - 128)) as i128,
994 low: 0,
995 }
996 }
997 }
998}
999
1000impl Shr<u8> for i256 {
1001 type Output = i256;
1002
1003 #[inline]
1004 fn shr(self, rhs: u8) -> Self::Output {
1005 if rhs == 0 {
1006 self
1007 } else if rhs < 128 {
1008 Self {
1009 high: self.high >> rhs,
1010 low: (self.low >> rhs) | ((self.high as u128) << (128 - rhs)),
1011 }
1012 } else {
1013 Self {
1014 high: self.high >> 127,
1015 low: (self.high >> (rhs - 128)) as u128,
1016 }
1017 }
1018 }
1019}
1020
1021impl WrappingShl for i256 {
1022 #[inline]
1023 fn wrapping_shl(&self, rhs: u32) -> i256 {
1024 (*self).shl(rhs as u8)
1026 }
1027}
1028
1029impl WrappingShr for i256 {
1030 #[inline]
1031 fn wrapping_shr(&self, rhs: u32) -> i256 {
1032 (*self).shr(rhs as u8)
1034 }
1035}
1036
1037macro_rules! define_standard_shift {
1040 ($trait_name:ident, $method:ident, [$($t:ty),+]) => {
1042 $(define_standard_shift!($trait_name, $method, $t);)+
1043 };
1044 ($trait_name:ident, $method:ident, $t:ty) => {
1046 impl $trait_name<$t> for i256 {
1047 type Output = i256;
1048
1049 #[inline]
1050 fn $method(self, rhs: $t) -> Self::Output {
1051 let rhs = u8::try_from(rhs).expect("rhs overflow for shift");
1052 self.$method(rhs)
1054 }
1055 }
1056 };
1057}
1058
1059define_standard_shift!(
1060 Shl,
1061 shl,
1062 [u16, u32, u64, u128, usize, i16, i32, i64, i128, isize]
1063);
1064define_standard_shift!(
1065 Shr,
1066 shr,
1067 [u16, u32, u64, u128, usize, i16, i32, i64, i128, isize]
1068);
1069
1070macro_rules! define_as_primitive {
1071 ($native_ty:ty) => {
1072 impl AsPrimitive<i256> for $native_ty {
1073 fn as_(self) -> i256 {
1074 i256::from_i128(self as i128)
1075 }
1076 }
1077 };
1078}
1079
1080define_as_primitive!(i8);
1081define_as_primitive!(i16);
1082define_as_primitive!(i32);
1083define_as_primitive!(i64);
1084define_as_primitive!(u8);
1085define_as_primitive!(u16);
1086define_as_primitive!(u32);
1087define_as_primitive!(u64);
1088
1089impl ToPrimitive for i256 {
1090 fn to_i64(&self) -> Option<i64> {
1091 i64::try_from(i256::to_i128(*self)?).ok()
1092 }
1093
1094 fn to_f64(&self) -> Option<f64> {
1095 match *self {
1096 Self::MIN => Some(-2_f64.powi(255)),
1097 Self::ZERO => Some(0f64),
1098 Self::ONE => Some(1f64),
1099 n => Some(Self::i256_to_f64(n)),
1100 }
1101 }
1102
1103 fn to_u64(&self) -> Option<u64> {
1104 u64::try_from(i256::to_i128(*self)?).ok()
1105 }
1106}
1107
1108impl CheckedNeg for i256 {
1111 fn checked_neg(&self) -> Option<Self> {
1112 (*self).checked_neg()
1113 }
1114}
1115
1116impl CheckedAdd for i256 {
1117 fn checked_add(&self, v: &i256) -> Option<Self> {
1118 (*self).checked_add(*v)
1119 }
1120}
1121
1122impl CheckedSub for i256 {
1123 fn checked_sub(&self, v: &i256) -> Option<Self> {
1124 (*self).checked_sub(*v)
1125 }
1126}
1127
1128impl CheckedDiv for i256 {
1129 fn checked_div(&self, v: &i256) -> Option<Self> {
1130 (*self).checked_div(*v)
1131 }
1132}
1133
1134impl CheckedMul for i256 {
1135 fn checked_mul(&self, v: &i256) -> Option<Self> {
1136 (*self).checked_mul(*v)
1137 }
1138}
1139
1140impl CheckedRem for i256 {
1141 fn checked_rem(&self, v: &i256) -> Option<Self> {
1142 (*self).checked_rem(*v)
1143 }
1144}
1145
1146impl CheckedShl for i256 {
1147 fn checked_shl(&self, rhs: u32) -> Option<Self> {
1148 let rhs = u8::try_from(rhs).ok()?;
1149 Some(self.shl(rhs))
1150 }
1151}
1152
1153impl CheckedShr for i256 {
1154 fn checked_shr(&self, rhs: u32) -> Option<Self> {
1155 let rhs = u8::try_from(rhs).ok()?;
1156 Some(self.shr(rhs))
1157 }
1158}
1159
1160impl WrappingAdd for i256 {
1163 fn wrapping_add(&self, v: &Self) -> Self {
1164 (*self).wrapping_add(*v)
1165 }
1166}
1167
1168impl WrappingSub for i256 {
1169 fn wrapping_sub(&self, v: &Self) -> Self {
1170 (*self).wrapping_sub(*v)
1171 }
1172}
1173
1174impl WrappingMul for i256 {
1175 fn wrapping_mul(&self, v: &Self) -> Self {
1176 (*self).wrapping_mul(*v)
1177 }
1178}
1179
1180impl WrappingNeg for i256 {
1181 fn wrapping_neg(&self) -> Self {
1182 (*self).wrapping_neg()
1183 }
1184}
1185
1186impl SaturatingAdd for i256 {
1189 fn saturating_add(&self, v: &Self) -> Self {
1190 self.checked_add(v).unwrap_or_else(|| {
1191 if v.is_negative() {
1192 i256::MIN
1193 } else {
1194 i256::MAX
1195 }
1196 })
1197 }
1198}
1199
1200impl SaturatingSub for i256 {
1201 fn saturating_sub(&self, v: &Self) -> Self {
1202 self.checked_sub(v).unwrap_or_else(|| {
1203 if v.is_negative() {
1204 i256::MAX
1205 } else {
1206 i256::MIN
1207 }
1208 })
1209 }
1210}
1211
1212impl SaturatingMul for i256 {
1213 fn saturating_mul(&self, v: &Self) -> Self {
1214 self.checked_mul(v).unwrap_or_else(|| {
1215 if v.is_negative() == self.is_negative() {
1216 i256::MAX
1217 } else {
1218 i256::MIN
1219 }
1220 })
1221 }
1222}
1223
1224impl MulAdd for i256 {
1225 type Output = i256;
1226
1227 fn mul_add(self, a: Self, b: Self) -> Self::Output {
1228 (self * a) + b
1229 }
1230}
1231
1232impl MulAddAssign for i256 {
1233 fn mul_add_assign(&mut self, a: Self, b: Self) {
1234 *self = self.mul_add(a, b)
1235 }
1236}
1237
1238impl Zero for i256 {
1239 fn zero() -> Self {
1240 i256::ZERO
1241 }
1242
1243 fn is_zero(&self) -> bool {
1244 *self == i256::ZERO
1245 }
1246}
1247
1248impl ConstZero for i256 {
1249 const ZERO: Self = i256::ZERO;
1250}
1251
1252impl One for i256 {
1253 fn one() -> Self {
1254 i256::ONE
1255 }
1256
1257 fn is_one(&self) -> bool {
1258 *self == i256::ONE
1259 }
1260}
1261
1262impl ConstOne for i256 {
1263 const ONE: Self = i256::ONE;
1264}
1265
1266impl Num for i256 {
1267 type FromStrRadixErr = ParseI256Error;
1268
1269 fn from_str_radix(str: &str, radix: u32) -> Result<Self, Self::FromStrRadixErr> {
1270 if radix == 10 {
1271 str.parse()
1272 } else {
1273 Err(ParseI256Error {})
1275 }
1276 }
1277}
1278
1279impl Signed for i256 {
1280 fn abs(&self) -> Self {
1281 self.wrapping_abs()
1282 }
1283
1284 fn abs_sub(&self, other: &Self) -> Self {
1285 if self > other {
1286 self.wrapping_sub(other)
1287 } else {
1288 i256::ZERO
1289 }
1290 }
1291
1292 fn signum(&self) -> Self {
1293 (*self).signum()
1294 }
1295
1296 fn is_positive(&self) -> bool {
1297 (*self).is_positive()
1298 }
1299
1300 fn is_negative(&self) -> bool {
1301 (*self).is_negative()
1302 }
1303}
1304
1305impl Bounded for i256 {
1306 fn min_value() -> Self {
1307 i256::MIN
1308 }
1309
1310 fn max_value() -> Self {
1311 i256::MAX
1312 }
1313}
1314
1315impl Not for i256 {
1316 type Output = i256;
1317
1318 #[inline]
1319 fn not(self) -> Self::Output {
1320 Self::from_parts(!self.low, !self.high)
1321 }
1322}
1323
1324#[cfg(test)]
1325mod tests {
1326 use super::*;
1327 use num_traits::Signed;
1328 use rand::{RngExt, rng};
1329
1330 #[test]
1331 fn test_signed_cmp() {
1332 let a = i256::from_parts(i128::MAX as u128, 12);
1333 let b = i256::from_parts(i128::MIN as u128, 12);
1334 assert!(a < b);
1335
1336 let a = i256::from_parts(i128::MAX as u128, 12);
1337 let b = i256::from_parts(i128::MIN as u128, -12);
1338 assert!(a > b);
1339 }
1340
1341 #[test]
1342 fn test_to_i128() {
1343 let vals = [
1344 BigInt::from_i128(-1).unwrap(),
1345 BigInt::from_i128(i128::MAX).unwrap(),
1346 BigInt::from_i128(i128::MIN).unwrap(),
1347 BigInt::from_u128(u128::MIN).unwrap(),
1348 BigInt::from_u128(u128::MAX).unwrap(),
1349 ];
1350
1351 for v in vals {
1352 let (t, overflow) = i256::from_bigint_with_overflow(v.clone());
1353 assert!(!overflow);
1354 assert_eq!(t.to_i128(), v.to_i128(), "{v} vs {t}");
1355 }
1356 }
1357
1358 fn test_ops(il: i256, ir: i256) {
1360 let bl = BigInt::from_signed_bytes_le(&il.to_le_bytes());
1361 let br = BigInt::from_signed_bytes_le(&ir.to_le_bytes());
1362
1363 assert_eq!(il.cmp(&ir), bl.cmp(&br), "{bl} cmp {br}");
1365
1366 assert_eq!(i256::from_le_bytes(il.to_le_bytes()), il);
1368 assert_eq!(i256::from_be_bytes(il.to_be_bytes()), il);
1369 assert_eq!(i256::from_le_bytes(ir.to_le_bytes()), ir);
1370 assert_eq!(i256::from_be_bytes(ir.to_be_bytes()), ir);
1371
1372 assert_eq!(il.to_i128(), bl.to_i128(), "{bl}");
1374 assert_eq!(ir.to_i128(), br.to_i128(), "{br}");
1375
1376 let (abs, overflow) = i256::from_bigint_with_overflow(bl.abs());
1378 assert_eq!(il.wrapping_abs(), abs);
1379 assert_eq!(il.checked_abs().is_none(), overflow);
1380
1381 let (abs, overflow) = i256::from_bigint_with_overflow(br.abs());
1382 assert_eq!(ir.wrapping_abs(), abs);
1383 assert_eq!(ir.checked_abs().is_none(), overflow);
1384
1385 let (neg, overflow) = i256::from_bigint_with_overflow(bl.clone().neg());
1387 assert_eq!(il.wrapping_neg(), neg);
1388 assert_eq!(il.checked_neg().is_none(), overflow);
1389
1390 let (neg, overflow) = i256::from_bigint_with_overflow(br.clone().neg());
1392 assert_eq!(ir.wrapping_neg(), neg);
1393 assert_eq!(ir.checked_neg().is_none(), overflow);
1394
1395 let actual = il.wrapping_add(ir);
1397 let (expected, overflow) = i256::from_bigint_with_overflow(bl.clone() + br.clone());
1398 assert_eq!(actual, expected);
1399 assert_eq!(il.overflowing_add(ir), (expected, overflow));
1400
1401 let checked = il.checked_add(ir);
1402 match overflow {
1403 true => assert!(checked.is_none()),
1404 false => assert_eq!(checked, Some(actual)),
1405 }
1406
1407 let actual = il.wrapping_sub(ir);
1409 let (expected, overflow) = i256::from_bigint_with_overflow(bl.clone() - br.clone());
1410 assert_eq!(actual.to_string(), expected.to_string());
1411 assert_eq!(il.overflowing_sub(ir), (expected, overflow));
1412
1413 let checked = il.checked_sub(ir);
1414 match overflow {
1415 true => assert!(checked.is_none()),
1416 false => assert_eq!(checked, Some(actual), "{bl} - {br} = {expected}"),
1417 }
1418
1419 let actual = il.wrapping_mul(ir);
1421 let (expected, overflow) = i256::from_bigint_with_overflow(bl.clone() * br.clone());
1422 assert_eq!(actual.to_string(), expected.to_string());
1423
1424 let checked = il.checked_mul(ir);
1425 match overflow {
1426 true => assert!(
1427 checked.is_none(),
1428 "{il} * {ir} = {actual} vs {bl} * {br} = {expected}"
1429 ),
1430 false => assert_eq!(
1431 checked,
1432 Some(actual),
1433 "{il} * {ir} = {actual} vs {bl} * {br} = {expected}"
1434 ),
1435 }
1436
1437 if ir != i256::ZERO {
1439 let actual = il.wrapping_div(ir);
1440 let expected = bl.clone() / br.clone();
1441 let checked = il.checked_div(ir);
1442
1443 if ir == i256::MINUS_ONE && il == i256::MIN {
1444 assert_eq!(actual, i256::MIN);
1446 assert!(checked.is_none());
1447 } else {
1448 assert_eq!(actual.to_string(), expected.to_string());
1449 assert_eq!(checked.unwrap().to_string(), expected.to_string());
1450 }
1451 } else {
1452 assert!(il.checked_div(ir).is_none());
1454 }
1455
1456 if ir != i256::ZERO {
1458 let actual = il.wrapping_rem(ir);
1459 let expected = bl.clone() % br.clone();
1460 let checked = il.checked_rem(ir);
1461
1462 assert_eq!(actual.to_string(), expected.to_string(), "{il} % {ir}");
1463
1464 if ir == i256::MINUS_ONE && il == i256::MIN {
1465 assert!(checked.is_none());
1466 } else {
1467 assert_eq!(checked.unwrap().to_string(), expected.to_string());
1468 }
1469 } else {
1470 assert!(il.checked_rem(ir).is_none());
1472 }
1473
1474 for exp in [0, 1, 2, 3, 8, 100] {
1476 let actual = il.wrapping_pow(exp);
1477 let (expected, overflow) = i256::from_bigint_with_overflow(bl.clone().pow(exp));
1478 assert_eq!(actual.to_string(), expected.to_string());
1479
1480 let checked = il.checked_pow(exp);
1481 match overflow {
1482 true => assert!(
1483 checked.is_none(),
1484 "{il} ^ {exp} = {actual} vs {bl} * {exp} = {expected}"
1485 ),
1486 false => assert_eq!(
1487 checked,
1488 Some(actual),
1489 "{il} ^ {exp} = {actual} vs {bl} ^ {exp} = {expected}"
1490 ),
1491 }
1492 }
1493
1494 let actual = il & ir;
1496 let (expected, _) = i256::from_bigint_with_overflow(bl.clone() & br.clone());
1497 assert_eq!(actual.to_string(), expected.to_string());
1498
1499 let actual = il | ir;
1500 let (expected, _) = i256::from_bigint_with_overflow(bl.clone() | br.clone());
1501 assert_eq!(actual.to_string(), expected.to_string());
1502
1503 let actual = il ^ ir;
1504 let (expected, _) = i256::from_bigint_with_overflow(bl.clone() ^ br);
1505 assert_eq!(actual.to_string(), expected.to_string());
1506
1507 for shift in [0_u8, 1, 4, 126, 128, 129, 254, 255] {
1508 let actual = il << shift;
1509 let (expected, _) = i256::from_bigint_with_overflow(bl.clone() << shift);
1510 assert_eq!(actual.to_string(), expected.to_string());
1511
1512 let wrapping_actual = <i256 as WrappingShl>::wrapping_shl(&il, shift as u32);
1513 assert_eq!(wrapping_actual.to_string(), expected.to_string());
1514
1515 let actual = il >> shift;
1516 let (expected, _) = i256::from_bigint_with_overflow(bl.clone() >> shift);
1517 assert_eq!(actual.to_string(), expected.to_string());
1518
1519 let wrapping_actual = <i256 as WrappingShr>::wrapping_shr(&il, shift as u32);
1520 assert_eq!(wrapping_actual.to_string(), expected.to_string());
1521
1522 let wrapping_actual = <i256 as WrappingShr>::wrapping_shr(&il, 512 + shift as u32);
1524 assert_eq!(wrapping_actual.to_string(), expected.to_string());
1525 }
1526 }
1527
1528 #[test]
1529 fn test_overflowing_add() {
1530 const POSITIVE_OVERFLOW: (i256, bool) = i256::MAX.overflowing_add(i256::ONE);
1531 const NEGATIVE_OVERFLOW: (i256, bool) = i256::MIN.overflowing_add(i256::MINUS_ONE);
1532
1533 assert_eq!(POSITIVE_OVERFLOW, (i256::MIN, true));
1534 assert_eq!(NEGATIVE_OVERFLOW, (i256::MAX, true));
1535 assert_eq!(
1536 i256::from_parts(u128::MAX, 0).overflowing_add(i256::ONE),
1537 (i256::from_parts(0, 1), false)
1538 );
1539 assert_eq!(
1540 i256::ONE.overflowing_add(i256::from_i128(2)),
1541 (i256::from_i128(3), false)
1542 );
1543 }
1544
1545 #[test]
1546 fn test_overflowing_sub() {
1547 const NEGATIVE_OVERFLOW: (i256, bool) = i256::MIN.overflowing_sub(i256::ONE);
1548 const POSITIVE_OVERFLOW: (i256, bool) = i256::MAX.overflowing_sub(i256::MINUS_ONE);
1549
1550 assert_eq!(NEGATIVE_OVERFLOW, (i256::MAX, true));
1551 assert_eq!(POSITIVE_OVERFLOW, (i256::MIN, true));
1552 assert_eq!(
1553 i256::from_parts(0, 1).overflowing_sub(i256::ONE),
1554 (i256::from_parts(u128::MAX, 0), false)
1555 );
1556 assert_eq!(
1557 i256::from_i128(3).overflowing_sub(i256::from_i128(2)),
1558 (i256::ONE, false)
1559 );
1560 }
1561
1562 #[test]
1563 #[cfg_attr(miri, ignore)] fn test_i256() {
1565 let candidates = [
1566 i256::ZERO,
1567 i256::ONE,
1568 i256::MINUS_ONE,
1569 ConstZero::ZERO,
1570 ConstOne::ONE,
1571 i256::from_i128(2),
1572 i256::from_i128(-2),
1573 i256::from_parts(u128::MAX, 1),
1574 i256::from_parts(u128::MAX, -1),
1575 i256::from_parts(0, 1),
1576 i256::from_parts(0, -1),
1577 i256::from_parts(1, -1),
1578 i256::from_parts(1, 1),
1579 i256::from_parts(0, i128::MAX),
1580 i256::from_parts(0, i128::MIN),
1581 i256::from_parts(1, i128::MAX),
1582 i256::from_parts(1, i128::MIN),
1583 i256::from_parts(u128::MAX, i128::MIN),
1584 i256::from_parts(100, 32),
1585 i256::MIN,
1586 i256::MAX,
1587 i256::MIN >> 1,
1588 i256::MAX >> 1,
1589 i256::ONE << 127,
1590 i256::ONE << 128,
1591 i256::ONE << 129,
1592 i256::MINUS_ONE << 127,
1593 i256::MINUS_ONE << 128,
1594 i256::MINUS_ONE << 129,
1595 ];
1596
1597 for il in candidates {
1598 for ir in candidates {
1599 test_ops(il, ir)
1600 }
1601 }
1602 }
1603
1604 #[test]
1605 fn test_signed_ops() {
1606 assert_eq!(i256::from_i128(1).signum(), i256::ONE);
1608 assert_eq!(i256::from_i128(0).signum(), i256::ZERO);
1609 assert_eq!(i256::from_i128(-0).signum(), i256::ZERO);
1610 assert_eq!(i256::from_i128(-1).signum(), i256::MINUS_ONE);
1611
1612 assert!(i256::from_i128(1).is_positive());
1614 assert!(!i256::from_i128(0).is_positive());
1615 assert!(!i256::from_i128(-0).is_positive());
1616 assert!(!i256::from_i128(-1).is_positive());
1617
1618 assert!(!i256::from_i128(1).is_negative());
1620 assert!(!i256::from_i128(0).is_negative());
1621 assert!(!i256::from_i128(-0).is_negative());
1622 assert!(i256::from_i128(-1).is_negative());
1623 }
1624
1625 #[test]
1626 #[cfg_attr(miri, ignore)] fn test_i256_fuzz() {
1628 let mut rng = rng();
1629
1630 for _ in 0..1000 {
1631 let mut l = [0_u8; 32];
1632 let len = rng.random_range(0..32);
1633 l.iter_mut().take(len).for_each(|x| *x = rng.random());
1634
1635 let mut r = [0_u8; 32];
1636 let len = rng.random_range(0..32);
1637 r.iter_mut().take(len).for_each(|x| *x = rng.random());
1638
1639 test_ops(i256::from_le_bytes(l), i256::from_le_bytes(r))
1640 }
1641 }
1642
1643 #[test]
1644 fn test_i256_to_primitive() {
1645 let a = i256::MAX;
1646 assert!(a.to_i64().is_none());
1647 assert!(a.to_u64().is_none());
1648
1649 let a = i256::from_i128(i128::MAX);
1650 assert!(a.to_i64().is_none());
1651 assert!(a.to_u64().is_none());
1652
1653 let a = i256::from_i128(i64::MAX as i128);
1654 assert_eq!(a.to_i64().unwrap(), i64::MAX);
1655 assert_eq!(a.to_u64().unwrap(), i64::MAX as u64);
1656
1657 let a = i256::from_i128(i64::MAX as i128 + 1);
1658 assert!(a.to_i64().is_none());
1659 assert_eq!(a.to_u64().unwrap(), i64::MAX as u64 + 1);
1660
1661 let a = i256::MIN;
1662 assert!(a.to_i64().is_none());
1663 assert!(a.to_u64().is_none());
1664
1665 let a = i256::from_i128(i128::MIN);
1666 assert!(a.to_i64().is_none());
1667 assert!(a.to_u64().is_none());
1668
1669 let a = i256::from_i128(i64::MIN as i128);
1670 assert_eq!(a.to_i64().unwrap(), i64::MIN);
1671 assert!(a.to_u64().is_none());
1672
1673 let a = i256::from_i128(i64::MIN as i128 - 1);
1674 assert!(a.to_i64().is_none());
1675 assert!(a.to_u64().is_none());
1676
1677 let a = i256::from_i128((1i128 << 64) + 5);
1680 assert!(a.to_i64().is_none());
1681 assert!(a.to_u64().is_none());
1682 assert!(a.to_i32().is_none());
1683 assert!(a.to_i8().is_none());
1684
1685 let a = i256::from_i128(-((1i128 << 64) + 5));
1686 assert!(a.to_i64().is_none());
1687 assert!(a.to_u64().is_none());
1688 assert!(a.to_i32().is_none());
1689 assert!(a.to_i8().is_none());
1690
1691 let a = i256::from_i128(u64::MAX as i128);
1692 assert!(a.to_i64().is_none());
1693 assert_eq!(a.to_u64().unwrap(), u64::MAX);
1694
1695 let a = i256::from_parts(5, 1);
1696 assert!(a.to_i64().is_none());
1697 assert!(a.to_u64().is_none());
1698
1699 let a = i256::from_parts(u64::MAX as u128 + 5, 0);
1700 assert!(a.to_i64().is_none());
1701 assert!(a.to_u64().is_none());
1702 }
1703
1704 #[test]
1705 fn test_i256_as_i128() {
1706 let a = i256::from_i128(i128::MAX).wrapping_add(i256::from_i128(1));
1707 let i128 = a.as_i128();
1708 assert_eq!(i128, i128::MIN);
1709
1710 let a = i256::from_i128(i128::MAX).wrapping_add(i256::from_i128(2));
1711 let i128 = a.as_i128();
1712 assert_eq!(i128, i128::MIN + 1);
1713
1714 let a = i256::from_i128(i128::MIN).wrapping_sub(i256::from_i128(1));
1715 let i128 = a.as_i128();
1716 assert_eq!(i128, i128::MAX);
1717
1718 let a = i256::from_i128(i128::MIN).wrapping_sub(i256::from_i128(2));
1719 let i128 = a.as_i128();
1720 assert_eq!(i128, i128::MAX - 1);
1721 }
1722
1723 #[test]
1724 fn test_string_roundtrip() {
1725 let roundtrip_cases = [
1726 i256::ZERO,
1727 i256::ONE,
1728 i256::MINUS_ONE,
1729 i256::from_i128(123456789),
1730 i256::from_i128(-123456789),
1731 i256::from_i128(i128::MIN),
1732 i256::from_i128(i128::MAX),
1733 i256::MIN,
1734 i256::MAX,
1735 ];
1736 for case in roundtrip_cases {
1737 let formatted = case.to_string();
1738 let back: i256 = formatted.parse().unwrap();
1739 assert_eq!(case, back);
1740 }
1741 }
1742
1743 #[test]
1744 fn test_from_string() {
1745 let cases = [
1746 (
1747 "000000000000000000000000000000000000000011",
1748 Some(i256::from_i128(11)),
1749 ),
1750 (
1751 "-000000000000000000000000000000000000000011",
1752 Some(i256::from_i128(-11)),
1753 ),
1754 (
1755 "-0000000000000000000000000000000000000000123456789",
1756 Some(i256::from_i128(-123456789)),
1757 ),
1758 ("-", None),
1759 ("+", None),
1760 ("--1", None),
1761 ("-+1", None),
1762 ("000000000000000000000000000000000000000", Some(i256::ZERO)),
1763 ("0000000000000000000000000000000000000000-11", None),
1764 ("11-1111111111111111111111111111111111111", None),
1765 (
1766 "115792089237316195423570985008687907853269984665640564039457584007913129639936",
1767 None,
1768 ),
1769 ];
1770 for (case, expected) in cases {
1771 assert_eq!(i256::from_string(case), expected)
1772 }
1773 }
1774
1775 #[expect(clippy::op_ref)]
1776 fn test_reference_op(il: i256, ir: i256) {
1777 let r1 = il + ir;
1778 let r2 = &il + ir;
1779 let r3 = il + &ir;
1780 let r4 = &il + &ir;
1781 assert_eq!(r1, r2);
1782 assert_eq!(r1, r3);
1783 assert_eq!(r1, r4);
1784
1785 let r1 = il - ir;
1786 let r2 = &il - ir;
1787 let r3 = il - &ir;
1788 let r4 = &il - &ir;
1789 assert_eq!(r1, r2);
1790 assert_eq!(r1, r3);
1791 assert_eq!(r1, r4);
1792
1793 let r1 = il * ir;
1794 let r2 = &il * ir;
1795 let r3 = il * &ir;
1796 let r4 = &il * &ir;
1797 assert_eq!(r1, r2);
1798 assert_eq!(r1, r3);
1799 assert_eq!(r1, r4);
1800
1801 let r1 = il / ir;
1802 let r2 = &il / ir;
1803 let r3 = il / &ir;
1804 let r4 = &il / &ir;
1805 assert_eq!(r1, r2);
1806 assert_eq!(r1, r3);
1807 assert_eq!(r1, r4);
1808 }
1809
1810 #[test]
1811 fn test_i256_reference_op() {
1812 let candidates = [
1813 i256::ONE,
1814 i256::MINUS_ONE,
1815 i256::from_i128(2),
1816 i256::from_i128(-2),
1817 i256::from_i128(3),
1818 i256::from_i128(-3),
1819 ];
1820
1821 for il in candidates {
1822 for ir in candidates {
1823 test_reference_op(il, ir)
1824 }
1825 }
1826 }
1827
1828 #[test]
1829 fn test_decimal256_to_f64_typical_values() {
1830 let v = i256::from_i128(42_i128);
1831 assert_eq!(v.to_f64().unwrap(), 42.0);
1832
1833 let v = i256::from_i128(-123456789012345678i128);
1834 assert_eq!(v.to_f64().unwrap(), -123_456_789_012_345_680.0);
1835
1836 let v = i256::from_string("0").unwrap();
1837 assert_eq!(v.to_f64().unwrap(), 0.0);
1838
1839 let v = i256::from_string("1").unwrap();
1840 assert_eq!(v.to_f64().unwrap(), 1.0);
1841
1842 let mut rng = rng();
1843 for _ in 0..10 {
1844 let f64_value =
1845 (rng.random_range(i128::MIN..i128::MAX) as f64) * rng.random_range(0.0..1.0);
1846 let big = i256::from_f64(f64_value).unwrap();
1847 assert_eq!(big.to_f64().unwrap(), f64_value);
1848 }
1849 }
1850
1851 #[test]
1852 fn test_decimal256_to_f64_large_positive_value() {
1853 let max_f = f64::MAX;
1854 let big = i256::from_f64(max_f * 2.0).unwrap_or(i256::MAX);
1855 let out = big.to_f64().unwrap();
1856 assert!(out.is_finite() && out.is_sign_positive());
1857 }
1858
1859 #[test]
1860 fn test_decimal256_to_f64_large_negative_value() {
1861 let max_f = f64::MAX;
1862 let big_neg = i256::from_f64(-(max_f * 2.0)).unwrap_or(i256::MIN);
1863 let out = big_neg.to_f64().unwrap();
1864 assert!(out.is_finite() && out.is_sign_negative());
1865 }
1866
1867 #[test]
1868 fn test_num_traits() {
1869 let value = i256::from_i128(-5);
1870 assert_eq!(
1871 <i256 as CheckedNeg>::checked_neg(&value),
1872 Some(i256::from(5))
1873 );
1874
1875 assert_eq!(
1876 <i256 as CheckedAdd>::checked_add(&value, &value),
1877 Some(i256::from(-10))
1878 );
1879
1880 assert_eq!(
1881 <i256 as CheckedSub>::checked_sub(&value, &value),
1882 Some(i256::from(0))
1883 );
1884
1885 assert_eq!(
1886 <i256 as CheckedMul>::checked_mul(&value, &value),
1887 Some(i256::from(25))
1888 );
1889
1890 assert_eq!(
1891 <i256 as CheckedDiv>::checked_div(&value, &value),
1892 Some(i256::from(1))
1893 );
1894
1895 assert_eq!(
1896 <i256 as CheckedRem>::checked_rem(&value, &value),
1897 Some(i256::from(0))
1898 );
1899
1900 assert_eq!(
1901 <i256 as WrappingAdd>::wrapping_add(&value, &value),
1902 i256::from(-10)
1903 );
1904
1905 assert_eq!(
1906 <i256 as WrappingSub>::wrapping_sub(&value, &value),
1907 i256::from(0)
1908 );
1909
1910 assert_eq!(
1911 <i256 as WrappingMul>::wrapping_mul(&value, &value),
1912 i256::from(25)
1913 );
1914
1915 assert_eq!(<i256 as WrappingNeg>::wrapping_neg(&value), i256::from(5));
1916
1917 let result = <i256 as WrappingAdd>::wrapping_add(&i256::MAX, &i256::ONE);
1919 assert_eq!(result, i256::MIN);
1920
1921 assert_eq!(i256::MAX.saturating_add(&i256::ONE), i256::MAX);
1923 assert_eq!(i256::MIN.saturating_sub(&i256::ONE), i256::MIN);
1924 assert_eq!(i256::MIN.saturating_add(&i256::MINUS_ONE), i256::MIN);
1925 assert_eq!(i256::MAX.saturating_sub(&i256::MINUS_ONE), i256::MAX);
1926 assert_eq!(i256::MAX.saturating_mul(&i256::MAX), i256::MAX);
1927 assert_eq!(i256::MAX.saturating_mul(&i256::MIN), i256::MIN);
1928 assert_eq!(i256::MIN.saturating_mul(&i256::MAX), i256::MIN);
1929 assert_eq!(i256::MIN.saturating_mul(&i256::MIN), i256::MAX);
1930 assert_eq!(i256::MIN.saturating_mul(&i256::ONE), i256::MIN);
1931 assert_eq!(i256::MIN.saturating_mul(&i256::MINUS_ONE), i256::MAX);
1932 assert_eq!(
1933 i256::from(20).saturating_add(&i256::from(5)),
1934 i256::from(25)
1935 );
1936 assert_eq!(
1937 i256::from(20).saturating_sub(&i256::from(5)),
1938 i256::from(15)
1939 );
1940 assert_eq!(
1941 i256::from(20).saturating_mul(&i256::from(5)),
1942 i256::from(100)
1943 );
1944
1945 assert_eq!(
1947 i256::from(20).mul_add(i256::from(5), i256::from(10)),
1948 i256::from(110)
1949 );
1950
1951 let mut mul_add_value = i256::from(20);
1952 mul_add_value.mul_add_assign(i256::from(5), i256::from(10));
1953 assert_eq!(mul_add_value, i256::from(110));
1954
1955 let value = i256::from(-5);
1956 assert_eq!(<i256 as Signed>::abs(&value), i256::from(5));
1957
1958 assert_eq!(<i256 as One>::one(), i256::from(1));
1959 assert_eq!(<i256 as Zero>::zero(), i256::from(0));
1960
1961 assert_eq!(<i256 as Bounded>::min_value(), i256::MIN);
1962 assert_eq!(<i256 as Bounded>::max_value(), i256::MAX);
1963
1964 assert_eq!(!i256::ZERO, i256::MINUS_ONE);
1966 assert_eq!(!i256::MINUS_ONE, i256::ZERO);
1967 assert_eq!(!i256::ONE, i256::from_parts(u128::MAX - 1, -1));
1968 }
1969
1970 #[should_panic(expected = "rhs overflow for shift")]
1971 #[test]
1972 fn test_shl_panic_on_arg_overflow() {
1973 let value = i256::from(123);
1974 let rhs = std::hint::black_box(500);
1975 let _ = value << rhs;
1976 }
1977
1978 #[test]
1979 fn test_numtraits_from_str_radix() {
1980 assert_eq!(
1981 i256::from_str_radix("123456789", 10).expect("parsed"),
1982 i256::from(123456789)
1983 );
1984 assert_eq!(
1985 i256::from_str_radix("0", 10).expect("parsed"),
1986 i256::from(0)
1987 );
1988 assert!(i256::from_str_radix("abc", 10).is_err());
1989 assert!(i256::from_str_radix("0", 16).is_err());
1990 }
1991
1992 #[test]
1993 fn test_leading_zeros() {
1994 assert_eq!(i256::from(0).leading_zeros(), 256);
1996 assert_eq!(i256::from(1).leading_zeros(), 256 - 1);
1997 assert_eq!(i256::from(16).leading_zeros(), 256 - 5);
1998 assert_eq!(i256::from(17).leading_zeros(), 256 - 5);
1999
2000 assert_eq!(i256::from_parts(2, 16).leading_zeros(), 128 - 5);
2002 assert_eq!(i256::from_parts(2, i128::MAX).leading_zeros(), 1);
2003
2004 assert_eq!(i256::MAX.leading_zeros(), 1);
2005 assert_eq!(i256::from(-1).leading_zeros(), 0);
2006 }
2007
2008 #[test]
2009 fn test_trailing_zeros() {
2010 assert_eq!(i256::from(0).trailing_zeros(), 256);
2012 assert_eq!(i256::from(2).trailing_zeros(), 1);
2013 assert_eq!(i256::from(16).trailing_zeros(), 4);
2014 assert_eq!(i256::from(17).trailing_zeros(), 0);
2015 assert_eq!(i256::from_parts(0, i128::MAX).trailing_zeros(), 128);
2017 assert_eq!(i256::from_parts(0, 16).trailing_zeros(), 128 + 4);
2018 assert_eq!(i256::from_parts(2, i128::MAX).trailing_zeros(), 1);
2019
2020 assert_eq!(i256::MAX.trailing_zeros(), 0);
2021 assert_eq!(i256::from(-1).trailing_zeros(), 0);
2022 }
2023
2024 #[test]
2025 fn test_ilog() {
2026 let value = i256::from(128);
2027
2028 assert_eq!(value.ilog(i256::from(2)), 7);
2030 assert_eq!(value.ilog2(), 7);
2031
2032 assert_eq!(value.ilog(i256::from(10)), 2);
2034 assert_eq!(value.ilog10(), 2);
2035
2036 assert_eq!(value.checked_ilog(i256::from(-2)), None);
2038 assert_eq!(value.checked_ilog(i256::from(-10)), None);
2039 assert_eq!(value.checked_ilog(i256::from(0)), None);
2040 assert_eq!(value.checked_ilog(i256::from(1)), None);
2041
2042 let neg_value = i256::from(-128);
2044 assert_eq!(neg_value.checked_ilog(i256::from(2)), None);
2045 assert_eq!(neg_value.checked_ilog(i256::from(10)), None);
2046 assert_eq!(neg_value.checked_ilog10(), None);
2047 assert_eq!(neg_value.checked_ilog2(), None);
2048
2049 assert_eq!(i256::ZERO.checked_ilog(i256::from(2)), None);
2051 assert_eq!(i256::ZERO.checked_ilog(i256::from(10)), None);
2052 assert_eq!(i256::ZERO.checked_ilog10(), None);
2053 assert_eq!(i256::ZERO.checked_ilog2(), None);
2054
2055 assert_eq!(i256::from(2).checked_ilog(i256::from(2)), Some(1));
2057 assert_eq!(i256::from(3).checked_ilog(i256::from(3)), Some(1));
2058 assert_eq!(i256::from(5).checked_ilog(i256::from(5)), Some(1));
2059 assert_eq!(i256::from(1000).checked_ilog(i256::from(1000)), Some(1));
2060 assert_eq!(i256::from(2).checked_ilog2(), Some(1));
2061 assert_eq!(i256::from(2).ilog2(), 1);
2062 assert_eq!(i256::from(10).checked_ilog(i256::from(10)), Some(1));
2064
2065 assert_eq!(i256::from(3).checked_ilog(i256::from(5)), Some(0));
2067
2068 for base in [2i64, 3, 5, 7, 1000] {
2070 for v in 1i64..64 {
2071 let want = (v as u128).ilog(base as u128);
2072 assert_eq!(
2073 i256::from(v).checked_ilog(i256::from(base)),
2074 Some(want),
2075 "checked_ilog({v}, {base})"
2076 );
2077 }
2078 }
2079
2080 let value = i256::from_parts(100000000, 1234);
2081 assert_eq!(value.checked_ilog(i256::from(10)), Some(41));
2082 assert_eq!(value.checked_ilog10(), Some(41));
2083
2084 let large = i256::from_parts(100000000, i128::MAX);
2086 assert_eq!(large.checked_ilog(i256::from(2)), Some(254));
2088
2089 assert_eq!(large.checked_ilog(i256::from(10)), Some(76));
2091 assert_eq!(large.checked_ilog10(), Some(76));
2092
2093 assert_eq!(large.checked_ilog(i256::from(5)), Some(109));
2095
2096 assert!(i256::from(2).checked_pow(255).is_none());
2098 let value = i256::from(2).checked_pow(254).expect("construct");
2099 assert_eq!(value.checked_ilog(i256::from(2)), Some(254));
2100
2101 assert_eq!(i256::MAX.checked_ilog(i256::from(2)), Some(254));
2103 }
2104
2105 #[test]
2106 fn test_ilog10() {
2107 assert_eq!(i256::ZERO.checked_ilog10(), None);
2109 assert_eq!(i256::MINUS_ONE.checked_ilog10(), None);
2110 assert_eq!(i256::MAX.checked_ilog10(), Some(76));
2111 assert_eq!(i256::from(10).checked_ilog10(), Some(1));
2112
2113 assert_eq!(i256::from(1).checked_ilog10(), Some(0));
2115 assert_eq!(i256::from(9).checked_ilog10(), Some(0));
2116
2117 assert_eq!(i256::from(100).checked_ilog10(), Some(2));
2119 assert_eq!(i256::from_parts(u128::MAX, 0).checked_ilog10(), Some(38));
2121
2122 assert_eq!(i256::from_parts(0, 1).checked_ilog10(), Some(38));
2124
2125 let pow50 = i256::from(10).checked_pow(50).unwrap();
2127 assert_eq!(pow50.checked_ilog10(), Some(50));
2128
2129 let pow64 = i256::from(10).checked_pow(64).unwrap();
2131 assert_eq!(pow64.checked_ilog10(), Some(64));
2132 }
2133
2134 #[test]
2135 #[should_panic(expected = "ilog10 overflow")]
2136 fn test_ilog10_zero_panics() {
2137 let _ = i256::ZERO.ilog10();
2138 }
2139
2140 #[test]
2141 #[should_panic(expected = "ilog overflow")]
2142 fn test_ilog_zero_panics() {
2143 let _ = i256::ZERO.ilog(i256::from(5));
2144 }
2145
2146 #[test]
2147 #[should_panic(expected = "ilog2 overflow")]
2148 fn test_ilog2_zero_panics() {
2149 let _ = i256::ZERO.ilog2();
2150 }
2151}