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 BigInt::from_f64(v).and_then(|i| {
244 let (integer, overflow) = i256::from_bigint_with_overflow(i);
245 if overflow { None } else { Some(integer) }
246 })
247 }
248
249 #[inline]
251 pub const fn from_parts(low: u128, high: i128) -> Self {
252 Self { low, high }
253 }
254
255 pub const fn to_parts(self) -> (u128, i128) {
257 (self.low, self.high)
258 }
259
260 pub const fn to_i128(self) -> Option<i128> {
263 let as_i128 = self.low as i128;
264
265 let high_negative = self.high < 0;
266 let low_negative = as_i128 < 0;
267 let high_valid = self.high == -1 || self.high == 0;
268
269 if (high_negative == low_negative) && high_valid {
270 Some(self.low as i128)
271 } else {
272 None
273 }
274 }
275
276 pub const fn as_i128(self) -> i128 {
278 self.low as i128
279 }
280
281 #[inline]
283 pub const fn to_le_bytes(self) -> [u8; 32] {
284 let low = self.low.to_le_bytes();
285 let high = self.high.to_le_bytes();
286 let mut t = [0; 32];
287 let mut i = 0;
288 while i != 16 {
289 t[i] = low[i];
290 t[i + 16] = high[i];
291 i += 1;
292 }
293 t
294 }
295
296 #[inline]
298 pub const fn to_be_bytes(self) -> [u8; 32] {
299 let low = self.low.to_be_bytes();
300 let high = self.high.to_be_bytes();
301 let mut t = [0; 32];
302 let mut i = 0;
303 while i != 16 {
304 t[i] = high[i];
305 t[i + 16] = low[i];
306 i += 1;
307 }
308 t
309 }
310
311 fn from_bigint_with_overflow(v: BigInt) -> (Self, bool) {
314 let v_bytes = v.to_signed_bytes_le();
315 match v_bytes.len().cmp(&32) {
316 Ordering::Less => {
317 let mut bytes = if num_traits::Signed::is_negative(&v) {
318 [255_u8; 32]
319 } else {
320 [0; 32]
321 };
322 bytes[0..v_bytes.len()].copy_from_slice(&v_bytes[..v_bytes.len()]);
323 (Self::from_le_bytes(bytes), false)
324 }
325 Ordering::Equal => (Self::from_le_bytes(v_bytes.try_into().unwrap()), false),
326 Ordering::Greater => (Self::from_le_bytes(v_bytes[..32].try_into().unwrap()), true),
327 }
328 }
329
330 #[inline]
332 pub const fn wrapping_abs(self) -> Self {
333 let sa = self.high >> 127;
335 let sa = Self::from_parts(sa as u128, sa);
336
337 Self::from_parts(self.low ^ sa.low, self.high ^ sa.high).wrapping_sub(sa)
339 }
340
341 #[inline]
343 pub const fn checked_abs(self) -> Option<Self> {
344 if !self.is_eq(Self::MIN) {
345 Some(self.wrapping_abs())
346 } else {
347 None
348 }
349 }
350
351 #[inline]
353 pub const fn wrapping_neg(self) -> Self {
354 Self::from_parts(!self.low, !self.high).wrapping_add(i256::ONE)
355 }
356
357 #[inline]
359 pub const fn checked_neg(self) -> Option<Self> {
360 if !self.is_eq(Self::MIN) {
361 Some(self.wrapping_neg())
362 } else {
363 None
364 }
365 }
366
367 #[inline]
369 pub const fn wrapping_add(self, other: Self) -> Self {
370 let (low, carry) = self.low.overflowing_add(other.low);
371 let high = self.high.wrapping_add(other.high).wrapping_add(carry as _);
372 Self { low, high }
373 }
374
375 #[inline]
377 pub const fn checked_add(self, other: Self) -> Option<Self> {
378 let (r, overflow) = self.overflowing_add(other);
379
380 if overflow { None } else { Some(r) }
381 }
382
383 #[inline]
385 pub const fn wrapping_sub(self, other: Self) -> Self {
386 let (low, carry) = self.low.overflowing_sub(other.low);
387 let high = self.high.wrapping_sub(other.high).wrapping_sub(carry as _);
388 Self { low, high }
389 }
390
391 #[inline]
393 pub const fn checked_sub(self, other: Self) -> Option<Self> {
394 let (r, overflow) = self.overflowing_sub(other);
395
396 if overflow { None } else { Some(r) }
397 }
398
399 #[inline]
401 pub const fn wrapping_mul(self, other: Self) -> Self {
402 let (low, high) = mulx(self.low, other.low);
403
404 let hl = self.high.wrapping_mul(other.low as i128);
406 let lh = (self.low as i128).wrapping_mul(other.high);
407
408 Self {
409 low,
410 high: (high as i128).wrapping_add(hl).wrapping_add(lh),
411 }
412 }
413
414 const fn is_eq(&self, other: Self) -> bool {
416 (self.high == other.high) && (self.low == other.low)
417 }
418
419 #[inline]
421 pub const fn checked_mul(self, other: Self) -> Option<Self> {
422 if self.is_eq(Self::ZERO) || other.is_eq(Self::ZERO) {
423 return Some(i256::ZERO);
424 }
425
426 let l_sa = self.high >> 127;
428 let r_sa = other.high >> 127;
429 let out_sa = (l_sa ^ r_sa) as u128;
430
431 let l_abs = self.wrapping_abs();
433 let r_abs = other.wrapping_abs();
434
435 if l_abs.high != 0 && r_abs.high != 0 {
437 return None;
438 }
439
440 let (low, high) = mulx(l_abs.low, r_abs.low);
442
443 let Some(hl) = (l_abs.high as u128).checked_mul(r_abs.low) else {
445 return None;
446 };
447 let Some(lh) = l_abs.low.checked_mul(r_abs.high as u128) else {
448 return None;
449 };
450
451 let Some(high) = high.checked_add(hl) else {
452 return None;
453 };
454 let Some(high) = high.checked_add(lh) else {
455 return None;
456 };
457
458 let (low, c) = (low ^ out_sa).overflowing_sub(out_sa);
460 let high = (high ^ out_sa).wrapping_sub(out_sa).wrapping_sub(c as u128) as i128;
461
462 if high.is_negative() == (self.is_negative() ^ other.is_negative()) {
464 Some(Self { low, high })
465 } else {
466 None
467 }
468 }
469
470 #[inline]
473 fn div_rem(self, other: Self) -> Result<(Self, Self), DivRemError> {
474 if other == Self::ZERO {
475 return Err(DivRemError::DivideByZero);
476 }
477 if other == Self::MINUS_ONE && self == Self::MIN {
478 return Err(DivRemError::DivideOverflow);
479 }
480
481 let a = self.wrapping_abs();
482 let b = other.wrapping_abs();
483
484 let (div, rem) = div_rem(&a.as_digits(), &b.as_digits());
485 let div = Self::from_digits(div);
486 let rem = Self::from_digits(rem);
487
488 Ok((
489 if self.is_negative() == other.is_negative() {
490 div
491 } else {
492 div.wrapping_neg()
493 },
494 if self.is_negative() {
495 rem.wrapping_neg()
496 } else {
497 rem
498 },
499 ))
500 }
501
502 fn as_digits(self) -> [u64; 4] {
504 [
505 self.low as u64,
506 (self.low >> 64) as u64,
507 self.high as u64,
508 (self.high as u128 >> 64) as u64,
509 ]
510 }
511
512 fn from_digits(digits: [u64; 4]) -> Self {
514 Self::from_parts(
515 digits[0] as u128 | ((digits[1] as u128) << 64),
516 digits[2] as i128 | ((digits[3] as i128) << 64),
517 )
518 }
519
520 #[inline]
522 pub fn wrapping_div(self, other: Self) -> Self {
523 match self.div_rem(other) {
524 Ok((v, _)) => v,
525 Err(DivRemError::DivideByZero) => panic!("attempt to divide by zero"),
526 Err(_) => Self::MIN,
527 }
528 }
529
530 #[inline]
532 pub fn checked_div(self, other: Self) -> Option<Self> {
533 self.div_rem(other).map(|(v, _)| v).ok()
534 }
535
536 #[inline]
538 pub fn wrapping_rem(self, other: Self) -> Self {
539 match self.div_rem(other) {
540 Ok((_, v)) => v,
541 Err(DivRemError::DivideByZero) => panic!("attempt to divide by zero"),
542 Err(_) => Self::ZERO,
543 }
544 }
545
546 #[inline]
548 pub fn checked_rem(self, other: Self) -> Option<Self> {
549 self.div_rem(other).map(|(_, v)| v).ok()
550 }
551
552 #[inline]
554 pub const fn checked_pow(self, mut exp: u32) -> Option<Self> {
555 if exp == 0 {
556 return Some(i256::from_i128(1));
557 }
558
559 let mut base = self;
560 let mut acc: Self = i256::from_i128(1);
561
562 while exp > 1 {
563 if (exp & 1) == 1 {
564 let Some(next) = acc.checked_mul(base) else {
565 return None;
566 };
567 acc = next;
568 }
569 exp /= 2;
570 let Some(next) = base.checked_mul(base) else {
571 return None;
572 };
573 base = next;
574 }
575 acc.checked_mul(base)
580 }
581
582 #[inline]
584 pub const fn wrapping_pow(self, mut exp: u32) -> Self {
585 if exp == 0 {
586 return i256::from_i128(1);
587 }
588
589 let mut base = self;
590 let mut acc: Self = i256::from_i128(1);
591
592 while exp > 1 {
593 if (exp & 1) == 1 {
594 acc = acc.wrapping_mul(base);
595 }
596 exp /= 2;
597 base = base.wrapping_mul(base);
598 }
599
600 acc.wrapping_mul(base)
605 }
606
607 pub const fn signum(self) -> Self {
613 if self.is_positive() {
614 i256::ONE
615 } else if self.is_negative() {
616 i256::MINUS_ONE
617 } else {
618 i256::ZERO
619 }
620 }
621
622 #[inline]
624 pub const fn is_negative(self) -> bool {
625 self.high.is_negative()
626 }
627
628 pub const fn is_positive(self) -> bool {
630 self.high.is_positive() || self.high == 0 && self.low != 0
631 }
632
633 pub const fn leading_zeros(&self) -> u32 {
635 match self.high {
636 0 => u128::BITS + self.low.leading_zeros(),
637 _ => self.high.leading_zeros(),
638 }
639 }
640
641 pub const fn trailing_zeros(&self) -> u32 {
643 match self.low {
644 0 => u128::BITS + self.high.trailing_zeros(),
645 _ => self.low.trailing_zeros(),
646 }
647 }
648
649 fn redundant_leading_sign_bits_i256(n: i256) -> u8 {
650 let mask = n >> 255; ((n ^ mask).leading_zeros() - 1) as u8 }
653
654 fn i256_to_f64(input: i256) -> f64 {
655 let k = i256::redundant_leading_sign_bits_i256(input);
656 let n = input << k; let n = (n.high >> 64) as i64; (n as f64) * f64::powi(2.0, 192 - (k as i32)) }
660
661 #[inline]
664 pub fn checked_ilog(self, base: i256) -> Option<u32> {
665 if base == Self::from(10) {
666 return self.checked_ilog10();
668 }
669
670 if self <= Self::ZERO {
671 return None;
672 }
673 if base <= Self::ONE {
674 return None;
675 }
676 if self < base {
677 return Some(0);
678 }
679
680 let mut val = 1;
681 let mut base_exp = base;
682
683 let boundary = self.checked_div(base)?;
684 while base_exp <= boundary {
685 val += 1;
686 base_exp = base_exp.checked_mul(base)?;
687 }
688 Some(val)
689 }
690
691 #[inline]
694 pub fn ilog(self, base: i256) -> u32 {
695 self.checked_ilog(base)
696 .unwrap_or_else(|| panic!("ilog overflow with {self} and base {base}"))
697 }
698
699 #[inline]
702 pub fn checked_ilog10(self) -> Option<u32> {
703 if self <= Self::ZERO {
704 return None;
705 }
706 if self < Self::from(10) {
707 return Some(0);
708 }
709
710 let pow_64: i256 = i256::from(10).checked_pow(64).unwrap();
713 let pow_32: i256 = i256::from(10).checked_pow(32).unwrap();
714 if self >= pow_64 {
715 let value = self.checked_div(pow_64)?;
716 debug_assert!(value.high == 0);
720 Some(64 + value.low.checked_ilog10()?)
721 } else if self >= pow_32 {
722 let value = self.checked_div(pow_32)?;
723 debug_assert!(value.high == 0);
727 Some(32 + value.low.checked_ilog10()?)
728 } else {
729 self.low.checked_ilog10()
731 }
732 }
733
734 #[inline]
737 pub fn ilog10(self) -> u32 {
738 self.checked_ilog10()
739 .unwrap_or_else(|| panic!("ilog10 overflow with {self}"))
740 }
741
742 #[inline]
745 pub fn checked_ilog2(self) -> Option<u32> {
746 self.checked_ilog(i256::from(2))
747 }
748
749 #[inline]
751 pub fn ilog2(self) -> u32 {
752 self.checked_ilog2()
753 .unwrap_or_else(|| panic!("ilog2 overflow with {self}"))
754 }
755
756 #[inline]
761 pub const fn overflowing_add(self, rhs: Self) -> (Self, bool) {
762 let (low, carry) = self.low.overflowing_add(rhs.low);
764
765 let high = (self.high as u128)
767 .wrapping_add(rhs.high as u128)
768 .wrapping_add(carry as u128) as i128;
769
770 let result = Self { low, high };
771
772 let overflow = (self.high < 0) == (rhs.high < 0) && (high < 0) != (self.high < 0);
776
777 (result, overflow)
778 }
779
780 #[inline]
785 pub const fn overflowing_sub(self, rhs: Self) -> (Self, bool) {
786 let (low, borrow) = self.low.overflowing_sub(rhs.low);
788
789 let high = (self.high as u128)
791 .wrapping_sub(rhs.high as u128)
792 .wrapping_sub(borrow as u128) as i128;
793
794 let result = Self { low, high };
795
796 let overflow = (self.high < 0) != (rhs.high < 0) && (high < 0) != (self.high < 0);
800
801 (result, overflow)
802 }
803}
804
805const fn split_array<const N: usize, const M: usize>(vals: [u8; N]) -> ([u8; M], [u8; M]) {
808 let mut a = [0; M];
809 let mut b = [0; M];
810 let mut i = 0;
811 while i != M {
812 a[i] = vals[i];
813 b[i] = vals[i + M];
814 i += 1;
815 }
816 (a, b)
817}
818
819#[inline]
825const fn mulx(a: u128, b: u128) -> (u128, u128) {
826 const fn split(a: u128) -> (u128, u128) {
827 (a & (u64::MAX as u128), a >> 64)
828 }
829
830 const MASK: u128 = u64::MAX as _;
831
832 let (a_low, a_high) = split(a);
833 let (b_low, b_high) = split(b);
834
835 let (mut low, mut carry) = split(a_low * b_low);
837 carry += a_high * b_low;
838
839 low += carry << 64;
841 let mut high = carry >> 64;
842
843 carry = low >> 64;
845 low &= MASK;
846
847 carry += b_high * a_low;
849
850 low += carry << 64;
852 high += carry >> 64;
853
854 high += a_high * b_high;
856
857 (low, high)
858}
859
860derive_arith!(
861 i256,
862 Add,
863 AddAssign,
864 add,
865 add_assign,
866 wrapping_add,
867 checked_add
868);
869derive_arith!(
870 i256,
871 Sub,
872 SubAssign,
873 sub,
874 sub_assign,
875 wrapping_sub,
876 checked_sub
877);
878derive_arith!(
879 i256,
880 Mul,
881 MulAssign,
882 mul,
883 mul_assign,
884 wrapping_mul,
885 checked_mul
886);
887derive_arith!(
888 i256,
889 Div,
890 DivAssign,
891 div,
892 div_assign,
893 wrapping_div,
894 checked_div
895);
896derive_arith!(
897 i256,
898 Rem,
899 RemAssign,
900 rem,
901 rem_assign,
902 wrapping_rem,
903 checked_rem
904);
905
906impl Neg for i256 {
907 type Output = i256;
908
909 #[cfg(debug_assertions)]
910 fn neg(self) -> Self::Output {
911 self.checked_neg().expect("i256 overflow")
912 }
913
914 #[cfg(not(debug_assertions))]
915 fn neg(self) -> Self::Output {
916 self.wrapping_neg()
917 }
918}
919
920impl BitAnd for i256 {
921 type Output = i256;
922
923 #[inline]
924 fn bitand(self, rhs: Self) -> Self::Output {
925 Self {
926 low: self.low & rhs.low,
927 high: self.high & rhs.high,
928 }
929 }
930}
931
932impl BitOr for i256 {
933 type Output = i256;
934
935 #[inline]
936 fn bitor(self, rhs: Self) -> Self::Output {
937 Self {
938 low: self.low | rhs.low,
939 high: self.high | rhs.high,
940 }
941 }
942}
943
944impl BitXor for i256 {
945 type Output = i256;
946
947 #[inline]
948 fn bitxor(self, rhs: Self) -> Self::Output {
949 Self {
950 low: self.low ^ rhs.low,
951 high: self.high ^ rhs.high,
952 }
953 }
954}
955
956impl Shl<u8> for i256 {
957 type Output = i256;
958
959 #[inline]
960 fn shl(self, rhs: u8) -> Self::Output {
961 if rhs == 0 {
962 self
963 } else if rhs < 128 {
964 Self {
965 high: (self.high << rhs) | (self.low >> (128 - rhs)) as i128,
966 low: self.low << rhs,
967 }
968 } else {
969 Self {
970 high: (self.low << (rhs - 128)) as i128,
971 low: 0,
972 }
973 }
974 }
975}
976
977impl Shr<u8> for i256 {
978 type Output = i256;
979
980 #[inline]
981 fn shr(self, rhs: u8) -> Self::Output {
982 if rhs == 0 {
983 self
984 } else if rhs < 128 {
985 Self {
986 high: self.high >> rhs,
987 low: (self.low >> rhs) | ((self.high as u128) << (128 - rhs)),
988 }
989 } else {
990 Self {
991 high: self.high >> 127,
992 low: (self.high >> (rhs - 128)) as u128,
993 }
994 }
995 }
996}
997
998impl WrappingShl for i256 {
999 #[inline]
1000 fn wrapping_shl(&self, rhs: u32) -> i256 {
1001 (*self).shl(rhs as u8)
1003 }
1004}
1005
1006impl WrappingShr for i256 {
1007 #[inline]
1008 fn wrapping_shr(&self, rhs: u32) -> i256 {
1009 (*self).shr(rhs as u8)
1011 }
1012}
1013
1014macro_rules! define_standard_shift {
1017 ($trait_name:ident, $method:ident, [$($t:ty),+]) => {
1019 $(define_standard_shift!($trait_name, $method, $t);)+
1020 };
1021 ($trait_name:ident, $method:ident, $t:ty) => {
1023 impl $trait_name<$t> for i256 {
1024 type Output = i256;
1025
1026 #[inline]
1027 fn $method(self, rhs: $t) -> Self::Output {
1028 let rhs = u8::try_from(rhs).expect("rhs overflow for shift");
1029 self.$method(rhs)
1031 }
1032 }
1033 };
1034}
1035
1036define_standard_shift!(
1037 Shl,
1038 shl,
1039 [u16, u32, u64, u128, usize, i16, i32, i64, i128, isize]
1040);
1041define_standard_shift!(
1042 Shr,
1043 shr,
1044 [u16, u32, u64, u128, usize, i16, i32, i64, i128, isize]
1045);
1046
1047macro_rules! define_as_primitive {
1048 ($native_ty:ty) => {
1049 impl AsPrimitive<i256> for $native_ty {
1050 fn as_(self) -> i256 {
1051 i256::from_i128(self as i128)
1052 }
1053 }
1054 };
1055}
1056
1057define_as_primitive!(i8);
1058define_as_primitive!(i16);
1059define_as_primitive!(i32);
1060define_as_primitive!(i64);
1061define_as_primitive!(u8);
1062define_as_primitive!(u16);
1063define_as_primitive!(u32);
1064define_as_primitive!(u64);
1065
1066impl ToPrimitive for i256 {
1067 fn to_i64(&self) -> Option<i64> {
1068 let as_i128 = self.low as i128;
1069
1070 let high_negative = self.high < 0;
1071 let low_negative = as_i128 < 0;
1072 let high_valid = self.high == -1 || self.high == 0;
1073
1074 if high_negative == low_negative && high_valid {
1075 let (low_bytes, high_bytes) = split_array(u128::to_le_bytes(self.low));
1076 let high = i64::from_le_bytes(high_bytes);
1077 let low = i64::from_le_bytes(low_bytes);
1078
1079 let high_negative = high < 0;
1080 let low_negative = low < 0;
1081 let high_valid = self.high == -1 || self.high == 0;
1082
1083 (high_negative == low_negative && high_valid).then_some(low)
1084 } else {
1085 None
1086 }
1087 }
1088
1089 fn to_f64(&self) -> Option<f64> {
1090 match *self {
1091 Self::MIN => Some(-2_f64.powi(255)),
1092 Self::ZERO => Some(0f64),
1093 Self::ONE => Some(1f64),
1094 n => Some(Self::i256_to_f64(n)),
1095 }
1096 }
1097
1098 fn to_u64(&self) -> Option<u64> {
1099 let as_i128 = self.low as i128;
1100
1101 let high_negative = self.high < 0;
1102 let low_negative = as_i128 < 0;
1103 let high_valid = self.high == -1 || self.high == 0;
1104
1105 if high_negative == low_negative && high_valid {
1106 self.low.to_u64()
1107 } else {
1108 None
1109 }
1110 }
1111}
1112
1113impl CheckedNeg for i256 {
1116 fn checked_neg(&self) -> Option<Self> {
1117 (*self).checked_neg()
1118 }
1119}
1120
1121impl CheckedAdd for i256 {
1122 fn checked_add(&self, v: &i256) -> Option<Self> {
1123 (*self).checked_add(*v)
1124 }
1125}
1126
1127impl CheckedSub for i256 {
1128 fn checked_sub(&self, v: &i256) -> Option<Self> {
1129 (*self).checked_sub(*v)
1130 }
1131}
1132
1133impl CheckedDiv for i256 {
1134 fn checked_div(&self, v: &i256) -> Option<Self> {
1135 (*self).checked_div(*v)
1136 }
1137}
1138
1139impl CheckedMul for i256 {
1140 fn checked_mul(&self, v: &i256) -> Option<Self> {
1141 (*self).checked_mul(*v)
1142 }
1143}
1144
1145impl CheckedRem for i256 {
1146 fn checked_rem(&self, v: &i256) -> Option<Self> {
1147 (*self).checked_rem(*v)
1148 }
1149}
1150
1151impl CheckedShl for i256 {
1152 fn checked_shl(&self, rhs: u32) -> Option<Self> {
1153 let rhs = u8::try_from(rhs).ok()?;
1154 Some(self.shl(rhs))
1155 }
1156}
1157
1158impl CheckedShr for i256 {
1159 fn checked_shr(&self, rhs: u32) -> Option<Self> {
1160 let rhs = u8::try_from(rhs).ok()?;
1161 Some(self.shr(rhs))
1162 }
1163}
1164
1165impl WrappingAdd for i256 {
1168 fn wrapping_add(&self, v: &Self) -> Self {
1169 (*self).wrapping_add(*v)
1170 }
1171}
1172
1173impl WrappingSub for i256 {
1174 fn wrapping_sub(&self, v: &Self) -> Self {
1175 (*self).wrapping_sub(*v)
1176 }
1177}
1178
1179impl WrappingMul for i256 {
1180 fn wrapping_mul(&self, v: &Self) -> Self {
1181 (*self).wrapping_mul(*v)
1182 }
1183}
1184
1185impl WrappingNeg for i256 {
1186 fn wrapping_neg(&self) -> Self {
1187 (*self).wrapping_neg()
1188 }
1189}
1190
1191impl SaturatingAdd for i256 {
1194 fn saturating_add(&self, v: &Self) -> Self {
1195 self.checked_add(v).unwrap_or_else(|| {
1196 if v.is_negative() {
1197 i256::MIN
1198 } else {
1199 i256::MAX
1200 }
1201 })
1202 }
1203}
1204
1205impl SaturatingSub for i256 {
1206 fn saturating_sub(&self, v: &Self) -> Self {
1207 self.checked_sub(v).unwrap_or_else(|| {
1208 if v.is_negative() {
1209 i256::MAX
1210 } else {
1211 i256::MIN
1212 }
1213 })
1214 }
1215}
1216
1217impl SaturatingMul for i256 {
1218 fn saturating_mul(&self, v: &Self) -> Self {
1219 self.checked_mul(v).unwrap_or_else(|| {
1220 if v.is_negative() == self.is_negative() {
1221 i256::MAX
1222 } else {
1223 i256::MIN
1224 }
1225 })
1226 }
1227}
1228
1229impl MulAdd for i256 {
1230 type Output = i256;
1231
1232 fn mul_add(self, a: Self, b: Self) -> Self::Output {
1233 (self * a) + b
1234 }
1235}
1236
1237impl MulAddAssign for i256 {
1238 fn mul_add_assign(&mut self, a: Self, b: Self) {
1239 *self = self.mul_add(a, b)
1240 }
1241}
1242
1243impl Zero for i256 {
1244 fn zero() -> Self {
1245 i256::ZERO
1246 }
1247
1248 fn is_zero(&self) -> bool {
1249 *self == i256::ZERO
1250 }
1251}
1252
1253impl ConstZero for i256 {
1254 const ZERO: Self = i256::ZERO;
1255}
1256
1257impl One for i256 {
1258 fn one() -> Self {
1259 i256::ONE
1260 }
1261
1262 fn is_one(&self) -> bool {
1263 *self == i256::ONE
1264 }
1265}
1266
1267impl ConstOne for i256 {
1268 const ONE: Self = i256::ONE;
1269}
1270
1271impl Num for i256 {
1272 type FromStrRadixErr = ParseI256Error;
1273
1274 fn from_str_radix(str: &str, radix: u32) -> Result<Self, Self::FromStrRadixErr> {
1275 if radix == 10 {
1276 str.parse()
1277 } else {
1278 Err(ParseI256Error {})
1280 }
1281 }
1282}
1283
1284impl Signed for i256 {
1285 fn abs(&self) -> Self {
1286 self.wrapping_abs()
1287 }
1288
1289 fn abs_sub(&self, other: &Self) -> Self {
1290 if self > other {
1291 self.wrapping_sub(other)
1292 } else {
1293 i256::ZERO
1294 }
1295 }
1296
1297 fn signum(&self) -> Self {
1298 (*self).signum()
1299 }
1300
1301 fn is_positive(&self) -> bool {
1302 (*self).is_positive()
1303 }
1304
1305 fn is_negative(&self) -> bool {
1306 (*self).is_negative()
1307 }
1308}
1309
1310impl Bounded for i256 {
1311 fn min_value() -> Self {
1312 i256::MIN
1313 }
1314
1315 fn max_value() -> Self {
1316 i256::MAX
1317 }
1318}
1319
1320impl Not for i256 {
1321 type Output = i256;
1322
1323 #[inline]
1324 fn not(self) -> Self::Output {
1325 Self::from_parts(!self.low, !self.high)
1326 }
1327}
1328
1329#[cfg(test)]
1330mod tests {
1331 use super::*;
1332 use num_traits::Signed;
1333 use rand::{RngExt, rng};
1334
1335 #[test]
1336 fn test_signed_cmp() {
1337 let a = i256::from_parts(i128::MAX as u128, 12);
1338 let b = i256::from_parts(i128::MIN as u128, 12);
1339 assert!(a < b);
1340
1341 let a = i256::from_parts(i128::MAX as u128, 12);
1342 let b = i256::from_parts(i128::MIN as u128, -12);
1343 assert!(a > b);
1344 }
1345
1346 #[test]
1347 fn test_to_i128() {
1348 let vals = [
1349 BigInt::from_i128(-1).unwrap(),
1350 BigInt::from_i128(i128::MAX).unwrap(),
1351 BigInt::from_i128(i128::MIN).unwrap(),
1352 BigInt::from_u128(u128::MIN).unwrap(),
1353 BigInt::from_u128(u128::MAX).unwrap(),
1354 ];
1355
1356 for v in vals {
1357 let (t, overflow) = i256::from_bigint_with_overflow(v.clone());
1358 assert!(!overflow);
1359 assert_eq!(t.to_i128(), v.to_i128(), "{v} vs {t}");
1360 }
1361 }
1362
1363 fn test_ops(il: i256, ir: i256) {
1365 let bl = BigInt::from_signed_bytes_le(&il.to_le_bytes());
1366 let br = BigInt::from_signed_bytes_le(&ir.to_le_bytes());
1367
1368 assert_eq!(il.cmp(&ir), bl.cmp(&br), "{bl} cmp {br}");
1370
1371 assert_eq!(i256::from_le_bytes(il.to_le_bytes()), il);
1373 assert_eq!(i256::from_be_bytes(il.to_be_bytes()), il);
1374 assert_eq!(i256::from_le_bytes(ir.to_le_bytes()), ir);
1375 assert_eq!(i256::from_be_bytes(ir.to_be_bytes()), ir);
1376
1377 assert_eq!(il.to_i128(), bl.to_i128(), "{bl}");
1379 assert_eq!(ir.to_i128(), br.to_i128(), "{br}");
1380
1381 let (abs, overflow) = i256::from_bigint_with_overflow(bl.abs());
1383 assert_eq!(il.wrapping_abs(), abs);
1384 assert_eq!(il.checked_abs().is_none(), overflow);
1385
1386 let (abs, overflow) = i256::from_bigint_with_overflow(br.abs());
1387 assert_eq!(ir.wrapping_abs(), abs);
1388 assert_eq!(ir.checked_abs().is_none(), overflow);
1389
1390 let (neg, overflow) = i256::from_bigint_with_overflow(bl.clone().neg());
1392 assert_eq!(il.wrapping_neg(), neg);
1393 assert_eq!(il.checked_neg().is_none(), overflow);
1394
1395 let (neg, overflow) = i256::from_bigint_with_overflow(br.clone().neg());
1397 assert_eq!(ir.wrapping_neg(), neg);
1398 assert_eq!(ir.checked_neg().is_none(), overflow);
1399
1400 let actual = il.wrapping_add(ir);
1402 let (expected, overflow) = i256::from_bigint_with_overflow(bl.clone() + br.clone());
1403 assert_eq!(actual, expected);
1404 assert_eq!(il.overflowing_add(ir), (expected, overflow));
1405
1406 let checked = il.checked_add(ir);
1407 match overflow {
1408 true => assert!(checked.is_none()),
1409 false => assert_eq!(checked, Some(actual)),
1410 }
1411
1412 let actual = il.wrapping_sub(ir);
1414 let (expected, overflow) = i256::from_bigint_with_overflow(bl.clone() - br.clone());
1415 assert_eq!(actual.to_string(), expected.to_string());
1416 assert_eq!(il.overflowing_sub(ir), (expected, overflow));
1417
1418 let checked = il.checked_sub(ir);
1419 match overflow {
1420 true => assert!(checked.is_none()),
1421 false => assert_eq!(checked, Some(actual), "{bl} - {br} = {expected}"),
1422 }
1423
1424 let actual = il.wrapping_mul(ir);
1426 let (expected, overflow) = i256::from_bigint_with_overflow(bl.clone() * br.clone());
1427 assert_eq!(actual.to_string(), expected.to_string());
1428
1429 let checked = il.checked_mul(ir);
1430 match overflow {
1431 true => assert!(
1432 checked.is_none(),
1433 "{il} * {ir} = {actual} vs {bl} * {br} = {expected}"
1434 ),
1435 false => assert_eq!(
1436 checked,
1437 Some(actual),
1438 "{il} * {ir} = {actual} vs {bl} * {br} = {expected}"
1439 ),
1440 }
1441
1442 if ir != i256::ZERO {
1444 let actual = il.wrapping_div(ir);
1445 let expected = bl.clone() / br.clone();
1446 let checked = il.checked_div(ir);
1447
1448 if ir == i256::MINUS_ONE && il == i256::MIN {
1449 assert_eq!(actual, i256::MIN);
1451 assert!(checked.is_none());
1452 } else {
1453 assert_eq!(actual.to_string(), expected.to_string());
1454 assert_eq!(checked.unwrap().to_string(), expected.to_string());
1455 }
1456 } else {
1457 assert!(il.checked_div(ir).is_none());
1459 }
1460
1461 if ir != i256::ZERO {
1463 let actual = il.wrapping_rem(ir);
1464 let expected = bl.clone() % br.clone();
1465 let checked = il.checked_rem(ir);
1466
1467 assert_eq!(actual.to_string(), expected.to_string(), "{il} % {ir}");
1468
1469 if ir == i256::MINUS_ONE && il == i256::MIN {
1470 assert!(checked.is_none());
1471 } else {
1472 assert_eq!(checked.unwrap().to_string(), expected.to_string());
1473 }
1474 } else {
1475 assert!(il.checked_rem(ir).is_none());
1477 }
1478
1479 for exp in [0, 1, 2, 3, 8, 100] {
1481 let actual = il.wrapping_pow(exp);
1482 let (expected, overflow) = i256::from_bigint_with_overflow(bl.clone().pow(exp));
1483 assert_eq!(actual.to_string(), expected.to_string());
1484
1485 let checked = il.checked_pow(exp);
1486 match overflow {
1487 true => assert!(
1488 checked.is_none(),
1489 "{il} ^ {exp} = {actual} vs {bl} * {exp} = {expected}"
1490 ),
1491 false => assert_eq!(
1492 checked,
1493 Some(actual),
1494 "{il} ^ {exp} = {actual} vs {bl} ^ {exp} = {expected}"
1495 ),
1496 }
1497 }
1498
1499 let actual = il & ir;
1501 let (expected, _) = i256::from_bigint_with_overflow(bl.clone() & br.clone());
1502 assert_eq!(actual.to_string(), expected.to_string());
1503
1504 let actual = il | ir;
1505 let (expected, _) = i256::from_bigint_with_overflow(bl.clone() | br.clone());
1506 assert_eq!(actual.to_string(), expected.to_string());
1507
1508 let actual = il ^ ir;
1509 let (expected, _) = i256::from_bigint_with_overflow(bl.clone() ^ br);
1510 assert_eq!(actual.to_string(), expected.to_string());
1511
1512 for shift in [0_u8, 1, 4, 126, 128, 129, 254, 255] {
1513 let actual = il << shift;
1514 let (expected, _) = i256::from_bigint_with_overflow(bl.clone() << shift);
1515 assert_eq!(actual.to_string(), expected.to_string());
1516
1517 let wrapping_actual = <i256 as WrappingShl>::wrapping_shl(&il, shift as u32);
1518 assert_eq!(wrapping_actual.to_string(), expected.to_string());
1519
1520 let actual = il >> shift;
1521 let (expected, _) = i256::from_bigint_with_overflow(bl.clone() >> shift);
1522 assert_eq!(actual.to_string(), expected.to_string());
1523
1524 let wrapping_actual = <i256 as WrappingShr>::wrapping_shr(&il, shift as u32);
1525 assert_eq!(wrapping_actual.to_string(), expected.to_string());
1526
1527 let wrapping_actual = <i256 as WrappingShr>::wrapping_shr(&il, 512 + shift as u32);
1529 assert_eq!(wrapping_actual.to_string(), expected.to_string());
1530 }
1531 }
1532
1533 #[test]
1534 fn test_overflowing_add() {
1535 const POSITIVE_OVERFLOW: (i256, bool) = i256::MAX.overflowing_add(i256::ONE);
1536 const NEGATIVE_OVERFLOW: (i256, bool) = i256::MIN.overflowing_add(i256::MINUS_ONE);
1537
1538 assert_eq!(POSITIVE_OVERFLOW, (i256::MIN, true));
1539 assert_eq!(NEGATIVE_OVERFLOW, (i256::MAX, true));
1540 assert_eq!(
1541 i256::from_parts(u128::MAX, 0).overflowing_add(i256::ONE),
1542 (i256::from_parts(0, 1), false)
1543 );
1544 assert_eq!(
1545 i256::ONE.overflowing_add(i256::from_i128(2)),
1546 (i256::from_i128(3), false)
1547 );
1548 }
1549
1550 #[test]
1551 fn test_overflowing_sub() {
1552 const NEGATIVE_OVERFLOW: (i256, bool) = i256::MIN.overflowing_sub(i256::ONE);
1553 const POSITIVE_OVERFLOW: (i256, bool) = i256::MAX.overflowing_sub(i256::MINUS_ONE);
1554
1555 assert_eq!(NEGATIVE_OVERFLOW, (i256::MAX, true));
1556 assert_eq!(POSITIVE_OVERFLOW, (i256::MIN, true));
1557 assert_eq!(
1558 i256::from_parts(0, 1).overflowing_sub(i256::ONE),
1559 (i256::from_parts(u128::MAX, 0), false)
1560 );
1561 assert_eq!(
1562 i256::from_i128(3).overflowing_sub(i256::from_i128(2)),
1563 (i256::ONE, false)
1564 );
1565 }
1566
1567 #[test]
1568 #[cfg_attr(miri, ignore)]
1569 fn test_i256() {
1570 let candidates = [
1571 i256::ZERO,
1572 i256::ONE,
1573 i256::MINUS_ONE,
1574 ConstZero::ZERO,
1575 ConstOne::ONE,
1576 i256::from_i128(2),
1577 i256::from_i128(-2),
1578 i256::from_parts(u128::MAX, 1),
1579 i256::from_parts(u128::MAX, -1),
1580 i256::from_parts(0, 1),
1581 i256::from_parts(0, -1),
1582 i256::from_parts(1, -1),
1583 i256::from_parts(1, 1),
1584 i256::from_parts(0, i128::MAX),
1585 i256::from_parts(0, i128::MIN),
1586 i256::from_parts(1, i128::MAX),
1587 i256::from_parts(1, i128::MIN),
1588 i256::from_parts(u128::MAX, i128::MIN),
1589 i256::from_parts(100, 32),
1590 i256::MIN,
1591 i256::MAX,
1592 i256::MIN >> 1,
1593 i256::MAX >> 1,
1594 i256::ONE << 127,
1595 i256::ONE << 128,
1596 i256::ONE << 129,
1597 i256::MINUS_ONE << 127,
1598 i256::MINUS_ONE << 128,
1599 i256::MINUS_ONE << 129,
1600 ];
1601
1602 for il in candidates {
1603 for ir in candidates {
1604 test_ops(il, ir)
1605 }
1606 }
1607 }
1608
1609 #[test]
1610 fn test_signed_ops() {
1611 assert_eq!(i256::from_i128(1).signum(), i256::ONE);
1613 assert_eq!(i256::from_i128(0).signum(), i256::ZERO);
1614 assert_eq!(i256::from_i128(-0).signum(), i256::ZERO);
1615 assert_eq!(i256::from_i128(-1).signum(), i256::MINUS_ONE);
1616
1617 assert!(i256::from_i128(1).is_positive());
1619 assert!(!i256::from_i128(0).is_positive());
1620 assert!(!i256::from_i128(-0).is_positive());
1621 assert!(!i256::from_i128(-1).is_positive());
1622
1623 assert!(!i256::from_i128(1).is_negative());
1625 assert!(!i256::from_i128(0).is_negative());
1626 assert!(!i256::from_i128(-0).is_negative());
1627 assert!(i256::from_i128(-1).is_negative());
1628 }
1629
1630 #[test]
1631 #[cfg_attr(miri, ignore)]
1632 fn test_i256_fuzz() {
1633 let mut rng = rng();
1634
1635 for _ in 0..1000 {
1636 let mut l = [0_u8; 32];
1637 let len = rng.random_range(0..32);
1638 l.iter_mut().take(len).for_each(|x| *x = rng.random());
1639
1640 let mut r = [0_u8; 32];
1641 let len = rng.random_range(0..32);
1642 r.iter_mut().take(len).for_each(|x| *x = rng.random());
1643
1644 test_ops(i256::from_le_bytes(l), i256::from_le_bytes(r))
1645 }
1646 }
1647
1648 #[test]
1649 fn test_i256_to_primitive() {
1650 let a = i256::MAX;
1651 assert!(a.to_i64().is_none());
1652 assert!(a.to_u64().is_none());
1653
1654 let a = i256::from_i128(i128::MAX);
1655 assert!(a.to_i64().is_none());
1656 assert!(a.to_u64().is_none());
1657
1658 let a = i256::from_i128(i64::MAX as i128);
1659 assert_eq!(a.to_i64().unwrap(), i64::MAX);
1660 assert_eq!(a.to_u64().unwrap(), i64::MAX as u64);
1661
1662 let a = i256::from_i128(i64::MAX as i128 + 1);
1663 assert!(a.to_i64().is_none());
1664 assert_eq!(a.to_u64().unwrap(), i64::MAX as u64 + 1);
1665
1666 let a = i256::MIN;
1667 assert!(a.to_i64().is_none());
1668 assert!(a.to_u64().is_none());
1669
1670 let a = i256::from_i128(i128::MIN);
1671 assert!(a.to_i64().is_none());
1672 assert!(a.to_u64().is_none());
1673
1674 let a = i256::from_i128(i64::MIN as i128);
1675 assert_eq!(a.to_i64().unwrap(), i64::MIN);
1676 assert!(a.to_u64().is_none());
1677
1678 let a = i256::from_i128(i64::MIN as i128 - 1);
1679 assert!(a.to_i64().is_none());
1680 assert!(a.to_u64().is_none());
1681 }
1682
1683 #[test]
1684 fn test_i256_as_i128() {
1685 let a = i256::from_i128(i128::MAX).wrapping_add(i256::from_i128(1));
1686 let i128 = a.as_i128();
1687 assert_eq!(i128, i128::MIN);
1688
1689 let a = i256::from_i128(i128::MAX).wrapping_add(i256::from_i128(2));
1690 let i128 = a.as_i128();
1691 assert_eq!(i128, i128::MIN + 1);
1692
1693 let a = i256::from_i128(i128::MIN).wrapping_sub(i256::from_i128(1));
1694 let i128 = a.as_i128();
1695 assert_eq!(i128, i128::MAX);
1696
1697 let a = i256::from_i128(i128::MIN).wrapping_sub(i256::from_i128(2));
1698 let i128 = a.as_i128();
1699 assert_eq!(i128, i128::MAX - 1);
1700 }
1701
1702 #[test]
1703 fn test_string_roundtrip() {
1704 let roundtrip_cases = [
1705 i256::ZERO,
1706 i256::ONE,
1707 i256::MINUS_ONE,
1708 i256::from_i128(123456789),
1709 i256::from_i128(-123456789),
1710 i256::from_i128(i128::MIN),
1711 i256::from_i128(i128::MAX),
1712 i256::MIN,
1713 i256::MAX,
1714 ];
1715 for case in roundtrip_cases {
1716 let formatted = case.to_string();
1717 let back: i256 = formatted.parse().unwrap();
1718 assert_eq!(case, back);
1719 }
1720 }
1721
1722 #[test]
1723 fn test_from_string() {
1724 let cases = [
1725 (
1726 "000000000000000000000000000000000000000011",
1727 Some(i256::from_i128(11)),
1728 ),
1729 (
1730 "-000000000000000000000000000000000000000011",
1731 Some(i256::from_i128(-11)),
1732 ),
1733 (
1734 "-0000000000000000000000000000000000000000123456789",
1735 Some(i256::from_i128(-123456789)),
1736 ),
1737 ("-", None),
1738 ("+", None),
1739 ("--1", None),
1740 ("-+1", None),
1741 ("000000000000000000000000000000000000000", Some(i256::ZERO)),
1742 ("0000000000000000000000000000000000000000-11", None),
1743 ("11-1111111111111111111111111111111111111", None),
1744 (
1745 "115792089237316195423570985008687907853269984665640564039457584007913129639936",
1746 None,
1747 ),
1748 ];
1749 for (case, expected) in cases {
1750 assert_eq!(i256::from_string(case), expected)
1751 }
1752 }
1753
1754 #[expect(clippy::op_ref)]
1755 fn test_reference_op(il: i256, ir: i256) {
1756 let r1 = il + ir;
1757 let r2 = &il + ir;
1758 let r3 = il + &ir;
1759 let r4 = &il + &ir;
1760 assert_eq!(r1, r2);
1761 assert_eq!(r1, r3);
1762 assert_eq!(r1, r4);
1763
1764 let r1 = il - ir;
1765 let r2 = &il - ir;
1766 let r3 = il - &ir;
1767 let r4 = &il - &ir;
1768 assert_eq!(r1, r2);
1769 assert_eq!(r1, r3);
1770 assert_eq!(r1, r4);
1771
1772 let r1 = il * ir;
1773 let r2 = &il * ir;
1774 let r3 = il * &ir;
1775 let r4 = &il * &ir;
1776 assert_eq!(r1, r2);
1777 assert_eq!(r1, r3);
1778 assert_eq!(r1, r4);
1779
1780 let r1 = il / ir;
1781 let r2 = &il / ir;
1782 let r3 = il / &ir;
1783 let r4 = &il / &ir;
1784 assert_eq!(r1, r2);
1785 assert_eq!(r1, r3);
1786 assert_eq!(r1, r4);
1787 }
1788
1789 #[test]
1790 fn test_i256_reference_op() {
1791 let candidates = [
1792 i256::ONE,
1793 i256::MINUS_ONE,
1794 i256::from_i128(2),
1795 i256::from_i128(-2),
1796 i256::from_i128(3),
1797 i256::from_i128(-3),
1798 ];
1799
1800 for il in candidates {
1801 for ir in candidates {
1802 test_reference_op(il, ir)
1803 }
1804 }
1805 }
1806
1807 #[test]
1808 #[cfg_attr(miri, ignore)]
1809 fn test_decimal256_to_f64_typical_values() {
1810 let v = i256::from_i128(42_i128);
1811 assert_eq!(v.to_f64().unwrap(), 42.0);
1812
1813 let v = i256::from_i128(-123456789012345678i128);
1814 assert_eq!(v.to_f64().unwrap(), -123_456_789_012_345_680.0);
1815
1816 let v = i256::from_string("0").unwrap();
1817 assert_eq!(v.to_f64().unwrap(), 0.0);
1818
1819 let v = i256::from_string("1").unwrap();
1820 assert_eq!(v.to_f64().unwrap(), 1.0);
1821
1822 let mut rng = rng();
1823 for _ in 0..10 {
1824 let f64_value =
1825 (rng.random_range(i128::MIN..i128::MAX) as f64) * rng.random_range(0.0..1.0);
1826 let big = i256::from_f64(f64_value).unwrap();
1827 assert_eq!(big.to_f64().unwrap(), f64_value);
1828 }
1829 }
1830
1831 #[test]
1832 fn test_decimal256_to_f64_large_positive_value() {
1833 let max_f = f64::MAX;
1834 let big = i256::from_f64(max_f * 2.0).unwrap_or(i256::MAX);
1835 let out = big.to_f64().unwrap();
1836 assert!(out.is_finite() && out.is_sign_positive());
1837 }
1838
1839 #[test]
1840 fn test_decimal256_to_f64_large_negative_value() {
1841 let max_f = f64::MAX;
1842 let big_neg = i256::from_f64(-(max_f * 2.0)).unwrap_or(i256::MIN);
1843 let out = big_neg.to_f64().unwrap();
1844 assert!(out.is_finite() && out.is_sign_negative());
1845 }
1846
1847 #[test]
1848 fn test_num_traits() {
1849 let value = i256::from_i128(-5);
1850 assert_eq!(
1851 <i256 as CheckedNeg>::checked_neg(&value),
1852 Some(i256::from(5))
1853 );
1854
1855 assert_eq!(
1856 <i256 as CheckedAdd>::checked_add(&value, &value),
1857 Some(i256::from(-10))
1858 );
1859
1860 assert_eq!(
1861 <i256 as CheckedSub>::checked_sub(&value, &value),
1862 Some(i256::from(0))
1863 );
1864
1865 assert_eq!(
1866 <i256 as CheckedMul>::checked_mul(&value, &value),
1867 Some(i256::from(25))
1868 );
1869
1870 assert_eq!(
1871 <i256 as CheckedDiv>::checked_div(&value, &value),
1872 Some(i256::from(1))
1873 );
1874
1875 assert_eq!(
1876 <i256 as CheckedRem>::checked_rem(&value, &value),
1877 Some(i256::from(0))
1878 );
1879
1880 assert_eq!(
1881 <i256 as WrappingAdd>::wrapping_add(&value, &value),
1882 i256::from(-10)
1883 );
1884
1885 assert_eq!(
1886 <i256 as WrappingSub>::wrapping_sub(&value, &value),
1887 i256::from(0)
1888 );
1889
1890 assert_eq!(
1891 <i256 as WrappingMul>::wrapping_mul(&value, &value),
1892 i256::from(25)
1893 );
1894
1895 assert_eq!(<i256 as WrappingNeg>::wrapping_neg(&value), i256::from(5));
1896
1897 let result = <i256 as WrappingAdd>::wrapping_add(&i256::MAX, &i256::ONE);
1899 assert_eq!(result, i256::MIN);
1900
1901 assert_eq!(i256::MAX.saturating_add(&i256::ONE), i256::MAX);
1903 assert_eq!(i256::MIN.saturating_sub(&i256::ONE), i256::MIN);
1904 assert_eq!(i256::MIN.saturating_add(&i256::MINUS_ONE), i256::MIN);
1905 assert_eq!(i256::MAX.saturating_sub(&i256::MINUS_ONE), i256::MAX);
1906 assert_eq!(i256::MAX.saturating_mul(&i256::MAX), i256::MAX);
1907 assert_eq!(i256::MAX.saturating_mul(&i256::MIN), i256::MIN);
1908 assert_eq!(i256::MIN.saturating_mul(&i256::MAX), i256::MIN);
1909 assert_eq!(i256::MIN.saturating_mul(&i256::MIN), i256::MAX);
1910 assert_eq!(i256::MIN.saturating_mul(&i256::ONE), i256::MIN);
1911 assert_eq!(i256::MIN.saturating_mul(&i256::MINUS_ONE), i256::MAX);
1912 assert_eq!(
1913 i256::from(20).saturating_add(&i256::from(5)),
1914 i256::from(25)
1915 );
1916 assert_eq!(
1917 i256::from(20).saturating_sub(&i256::from(5)),
1918 i256::from(15)
1919 );
1920 assert_eq!(
1921 i256::from(20).saturating_mul(&i256::from(5)),
1922 i256::from(100)
1923 );
1924
1925 assert_eq!(
1927 i256::from(20).mul_add(i256::from(5), i256::from(10)),
1928 i256::from(110)
1929 );
1930
1931 let mut mul_add_value = i256::from(20);
1932 mul_add_value.mul_add_assign(i256::from(5), i256::from(10));
1933 assert_eq!(mul_add_value, i256::from(110));
1934
1935 let value = i256::from(-5);
1936 assert_eq!(<i256 as Signed>::abs(&value), i256::from(5));
1937
1938 assert_eq!(<i256 as One>::one(), i256::from(1));
1939 assert_eq!(<i256 as Zero>::zero(), i256::from(0));
1940
1941 assert_eq!(<i256 as Bounded>::min_value(), i256::MIN);
1942 assert_eq!(<i256 as Bounded>::max_value(), i256::MAX);
1943
1944 assert_eq!(!i256::ZERO, i256::MINUS_ONE);
1946 assert_eq!(!i256::MINUS_ONE, i256::ZERO);
1947 assert_eq!(!i256::ONE, i256::from_parts(u128::MAX - 1, -1));
1948 }
1949
1950 #[should_panic(expected = "rhs overflow for shift")]
1951 #[test]
1952 fn test_shl_panic_on_arg_overflow() {
1953 let value = i256::from(123);
1954 let rhs = std::hint::black_box(500);
1955 let _ = value << rhs;
1956 }
1957
1958 #[test]
1959 fn test_numtraits_from_str_radix() {
1960 assert_eq!(
1961 i256::from_str_radix("123456789", 10).expect("parsed"),
1962 i256::from(123456789)
1963 );
1964 assert_eq!(
1965 i256::from_str_radix("0", 10).expect("parsed"),
1966 i256::from(0)
1967 );
1968 assert!(i256::from_str_radix("abc", 10).is_err());
1969 assert!(i256::from_str_radix("0", 16).is_err());
1970 }
1971
1972 #[test]
1973 fn test_leading_zeros() {
1974 assert_eq!(i256::from(0).leading_zeros(), 256);
1976 assert_eq!(i256::from(1).leading_zeros(), 256 - 1);
1977 assert_eq!(i256::from(16).leading_zeros(), 256 - 5);
1978 assert_eq!(i256::from(17).leading_zeros(), 256 - 5);
1979
1980 assert_eq!(i256::from_parts(2, 16).leading_zeros(), 128 - 5);
1982 assert_eq!(i256::from_parts(2, i128::MAX).leading_zeros(), 1);
1983
1984 assert_eq!(i256::MAX.leading_zeros(), 1);
1985 assert_eq!(i256::from(-1).leading_zeros(), 0);
1986 }
1987
1988 #[test]
1989 fn test_trailing_zeros() {
1990 assert_eq!(i256::from(0).trailing_zeros(), 256);
1992 assert_eq!(i256::from(2).trailing_zeros(), 1);
1993 assert_eq!(i256::from(16).trailing_zeros(), 4);
1994 assert_eq!(i256::from(17).trailing_zeros(), 0);
1995 assert_eq!(i256::from_parts(0, i128::MAX).trailing_zeros(), 128);
1997 assert_eq!(i256::from_parts(0, 16).trailing_zeros(), 128 + 4);
1998 assert_eq!(i256::from_parts(2, i128::MAX).trailing_zeros(), 1);
1999
2000 assert_eq!(i256::MAX.trailing_zeros(), 0);
2001 assert_eq!(i256::from(-1).trailing_zeros(), 0);
2002 }
2003
2004 #[test]
2005 fn test_ilog() {
2006 let value = i256::from(128);
2007
2008 assert_eq!(value.ilog(i256::from(2)), 7);
2010 assert_eq!(value.ilog2(), 7);
2011
2012 assert_eq!(value.ilog(i256::from(10)), 2);
2014 assert_eq!(value.ilog10(), 2);
2015
2016 assert_eq!(value.checked_ilog(i256::from(-2)), None);
2018 assert_eq!(value.checked_ilog(i256::from(-10)), None);
2019 assert_eq!(value.checked_ilog(i256::from(0)), None);
2020 assert_eq!(value.checked_ilog(i256::from(1)), None);
2021
2022 let neg_value = i256::from(-128);
2024 assert_eq!(neg_value.checked_ilog(i256::from(2)), None);
2025 assert_eq!(neg_value.checked_ilog(i256::from(10)), None);
2026 assert_eq!(neg_value.checked_ilog10(), None);
2027 assert_eq!(neg_value.checked_ilog2(), None);
2028
2029 assert_eq!(i256::ZERO.checked_ilog(i256::from(2)), None);
2031 assert_eq!(i256::ZERO.checked_ilog(i256::from(10)), None);
2032 assert_eq!(i256::ZERO.checked_ilog10(), None);
2033 assert_eq!(i256::ZERO.checked_ilog2(), None);
2034
2035 assert_eq!(i256::from(2).checked_ilog(i256::from(2)), Some(1));
2037 assert_eq!(i256::from(3).checked_ilog(i256::from(3)), Some(1));
2038 assert_eq!(i256::from(5).checked_ilog(i256::from(5)), Some(1));
2039 assert_eq!(i256::from(1000).checked_ilog(i256::from(1000)), Some(1));
2040 assert_eq!(i256::from(2).checked_ilog2(), Some(1));
2041 assert_eq!(i256::from(2).ilog2(), 1);
2042 assert_eq!(i256::from(10).checked_ilog(i256::from(10)), Some(1));
2044
2045 assert_eq!(i256::from(3).checked_ilog(i256::from(5)), Some(0));
2047
2048 for base in [2i64, 3, 5, 7, 1000] {
2050 for v in 1i64..64 {
2051 let want = (v as u128).ilog(base as u128);
2052 assert_eq!(
2053 i256::from(v).checked_ilog(i256::from(base)),
2054 Some(want),
2055 "checked_ilog({v}, {base})"
2056 );
2057 }
2058 }
2059
2060 let value = i256::from_parts(100000000, 1234);
2061 assert_eq!(value.checked_ilog(i256::from(10)), Some(41));
2062 assert_eq!(value.checked_ilog10(), Some(41));
2063
2064 let large = i256::from_parts(100000000, i128::MAX);
2066 assert_eq!(large.checked_ilog(i256::from(2)), Some(254));
2068
2069 assert_eq!(large.checked_ilog(i256::from(10)), Some(76));
2071 assert_eq!(large.checked_ilog10(), Some(76));
2072
2073 assert_eq!(large.checked_ilog(i256::from(5)), Some(109));
2075
2076 assert!(i256::from(2).checked_pow(255).is_none());
2078 let value = i256::from(2).checked_pow(254).expect("construct");
2079 assert_eq!(value.checked_ilog(i256::from(2)), Some(254));
2080
2081 assert_eq!(i256::MAX.checked_ilog(i256::from(2)), Some(254));
2083 }
2084
2085 #[test]
2086 fn test_ilog10() {
2087 assert_eq!(i256::ZERO.checked_ilog10(), None);
2089 assert_eq!(i256::MINUS_ONE.checked_ilog10(), None);
2090 assert_eq!(i256::MAX.checked_ilog10(), Some(76));
2091 assert_eq!(i256::from(10).checked_ilog10(), Some(1));
2092
2093 assert_eq!(i256::from(1).checked_ilog10(), Some(0));
2095 assert_eq!(i256::from(9).checked_ilog10(), Some(0));
2096
2097 assert_eq!(i256::from(100).checked_ilog10(), Some(2));
2099 assert_eq!(i256::from_parts(u128::MAX, 0).checked_ilog10(), Some(38));
2101
2102 assert_eq!(i256::from_parts(0, 1).checked_ilog10(), Some(38));
2104
2105 let pow50 = i256::from(10).checked_pow(50).unwrap();
2107 assert_eq!(pow50.checked_ilog10(), Some(50));
2108
2109 let pow64 = i256::from(10).checked_pow(64).unwrap();
2111 assert_eq!(pow64.checked_ilog10(), Some(64));
2112 }
2113
2114 #[test]
2115 #[should_panic(expected = "ilog10 overflow")]
2116 fn test_ilog10_zero_panics() {
2117 let _ = i256::ZERO.ilog10();
2118 }
2119
2120 #[test]
2121 #[should_panic(expected = "ilog overflow")]
2122 fn test_ilog_zero_panics() {
2123 let _ = i256::ZERO.ilog(i256::from(5));
2124 }
2125
2126 #[test]
2127 #[should_panic(expected = "ilog2 overflow")]
2128 fn test_ilog2_zero_panics() {
2129 let _ = i256::ZERO.ilog2();
2130 }
2131}