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