1use core::cmp::Ordering;
18
19#[cfg(kani)]
23#[repr(transparent)]
24#[derive(Clone, Copy, Debug, PartialEq, Eq)]
25pub struct U256([u128; 2]); #[cfg(kani)]
28impl U256 {
29 pub const ZERO: Self = Self([0, 0]);
30 pub const ONE: Self = Self([1, 0]);
31 pub const MAX: Self = Self([u128::MAX, u128::MAX]);
32
33 #[inline(always)]
34 pub const fn new(lo: u128, hi: u128) -> Self {
35 Self([lo, hi])
36 }
37
38 #[inline(always)]
39 pub const fn from_u128(v: u128) -> Self {
40 Self([v, 0])
41 }
42
43 #[inline(always)]
44 pub const fn from_u64(v: u64) -> Self {
45 Self([v as u128, 0])
46 }
47
48 #[inline(always)]
49 pub const fn lo(&self) -> u128 {
50 self.0[0]
51 }
52
53 #[inline(always)]
54 pub const fn hi(&self) -> u128 {
55 self.0[1]
56 }
57
58 #[inline(always)]
59 pub const fn is_zero(&self) -> bool {
60 self.0[0] == 0 && self.0[1] == 0
61 }
62
63 #[inline(always)]
64 pub fn try_into_u128(&self) -> Option<u128> {
65 if self.0[1] == 0 {
66 Some(self.0[0])
67 } else {
68 None
69 }
70 }
71
72 pub fn checked_add(self, rhs: U256) -> Option<U256> {
75 let (lo, carry) = self.0[0].overflowing_add(rhs.0[0]);
76 let hi = self.0[1].checked_add(rhs.0[1])?;
77 let hi = if carry { hi.checked_add(1)? } else { hi };
78 Some(U256([lo, hi]))
79 }
80
81 pub fn checked_sub(self, rhs: U256) -> Option<U256> {
82 let (lo, borrow) = self.0[0].overflowing_sub(rhs.0[0]);
83 let hi = self.0[1].checked_sub(rhs.0[1])?;
84 let hi = if borrow { hi.checked_sub(1)? } else { hi };
85 Some(U256([lo, hi]))
86 }
87
88 pub fn checked_mul(self, rhs: U256) -> Option<U256> {
89 if self.0[1] != 0 && rhs.0[1] != 0 {
104 return None;
105 }
106
107 let (prod_lo, prod_hi) = widening_mul_u128(self.0[0], rhs.0[0]);
108
109 let cross1 = if rhs.0[1] != 0 {
113 let (c, overflow) = widening_mul_u128(self.0[0], rhs.0[1]);
114 if overflow != 0 {
115 return None;
116 }
117 c
118 } else {
119 0u128
120 };
121
122 let cross2 = if self.0[1] != 0 {
123 let (c, overflow) = widening_mul_u128(self.0[1], rhs.0[0]);
124 if overflow != 0 {
125 return None;
126 }
127 c
128 } else {
129 0u128
130 };
131
132 let hi = prod_hi.checked_add(cross1)?;
133 let hi = hi.checked_add(cross2)?;
134
135 Some(U256([prod_lo, hi]))
136 }
137
138 pub fn checked_div(self, rhs: U256) -> Option<U256> {
139 if rhs.is_zero() {
140 return None;
141 }
142 Some(div_rem_u256(self, rhs).0)
143 }
144
145 pub fn checked_rem(self, rhs: U256) -> Option<U256> {
146 if rhs.is_zero() {
147 return None;
148 }
149 Some(div_rem_u256(self, rhs).1)
150 }
151
152 pub fn overflowing_add(self, rhs: U256) -> (U256, bool) {
155 let (lo, carry) = self.0[0].overflowing_add(rhs.0[0]);
156 let (hi, overflow1) = self.0[1].overflowing_add(rhs.0[1]);
157 let (hi, overflow2) = if carry {
158 hi.overflowing_add(1)
159 } else {
160 (hi, false)
161 };
162 (U256([lo, hi]), overflow1 || overflow2)
163 }
164
165 pub fn overflowing_sub(self, rhs: U256) -> (U256, bool) {
166 let (lo, borrow) = self.0[0].overflowing_sub(rhs.0[0]);
167 let (hi, underflow1) = self.0[1].overflowing_sub(rhs.0[1]);
168 let (hi, underflow2) = if borrow {
169 hi.overflowing_sub(1)
170 } else {
171 (hi, false)
172 };
173 (U256([lo, hi]), underflow1 || underflow2)
174 }
175
176 pub fn saturating_add(self, rhs: U256) -> U256 {
179 self.checked_add(rhs).unwrap_or(U256::MAX)
180 }
181
182 pub fn saturating_sub(self, rhs: U256) -> U256 {
183 self.checked_sub(rhs).unwrap_or(U256::ZERO)
184 }
185
186 pub fn shl(self, bits: u32) -> U256 {
189 if bits >= 256 {
190 return U256::ZERO;
191 }
192 if bits == 0 {
193 return self;
194 }
195 if bits >= 128 {
196 let s = bits - 128;
197 U256([0, self.0[0] << s])
198 } else {
199 let lo = self.0[0] << bits;
200 let hi = (self.0[1] << bits) | (self.0[0] >> (128 - bits));
201 U256([lo, hi])
202 }
203 }
204
205 pub fn shr(self, bits: u32) -> U256 {
206 if bits >= 256 {
207 return U256::ZERO;
208 }
209 if bits == 0 {
210 return self;
211 }
212 if bits >= 128 {
213 let s = bits - 128;
214 U256([self.0[1] >> s, 0])
215 } else {
216 let hi = self.0[1] >> bits;
217 let lo = (self.0[0] >> bits) | (self.0[1] << (128 - bits));
218 U256([lo, hi])
219 }
220 }
221
222 pub fn bitand(self, rhs: U256) -> U256 {
225 U256([self.0[0] & rhs.0[0], self.0[1] & rhs.0[1]])
226 }
227
228 pub fn bitor(self, rhs: U256) -> U256 {
229 U256([self.0[0] | rhs.0[0], self.0[1] | rhs.0[1]])
230 }
231}
232
233#[cfg(not(kani))]
237#[repr(C)]
238#[derive(Clone, Copy, Debug, PartialEq, Eq)]
239pub struct U256([u64; 4]); #[cfg(not(kani))]
242impl U256 {
243 pub const ZERO: Self = Self([0, 0, 0, 0]);
244 pub const ONE: Self = Self([1, 0, 0, 0]);
245 pub const MAX: Self = Self([u64::MAX, u64::MAX, u64::MAX, u64::MAX]);
246
247 #[inline]
249 pub const fn new(lo: u128, hi: u128) -> Self {
250 Self([lo as u64, (lo >> 64) as u64, hi as u64, (hi >> 64) as u64])
251 }
252
253 #[inline]
254 pub const fn from_u128(v: u128) -> Self {
255 Self::new(v, 0)
256 }
257
258 #[inline]
259 pub const fn from_u64(v: u64) -> Self {
260 Self([v, 0, 0, 0])
261 }
262
263 #[inline]
264 pub const fn lo(&self) -> u128 {
265 (self.0[0] as u128) | ((self.0[1] as u128) << 64)
266 }
267
268 #[inline]
269 pub const fn hi(&self) -> u128 {
270 (self.0[2] as u128) | ((self.0[3] as u128) << 64)
271 }
272
273 #[inline]
274 pub const fn is_zero(&self) -> bool {
275 self.0[0] == 0 && self.0[1] == 0 && self.0[2] == 0 && self.0[3] == 0
276 }
277
278 #[inline]
279 pub fn try_into_u128(&self) -> Option<u128> {
280 if self.0[2] == 0 && self.0[3] == 0 {
281 Some(self.lo())
282 } else {
283 None
284 }
285 }
286
287 pub fn checked_add(self, rhs: U256) -> Option<U256> {
290 let (lo, carry) = add_u128_carry(self.lo(), rhs.lo(), false);
291 let (hi, overflow) = add_u128_carry(self.hi(), rhs.hi(), carry);
292 if overflow {
293 None
294 } else {
295 Some(U256::new(lo, hi))
296 }
297 }
298
299 pub fn checked_sub(self, rhs: U256) -> Option<U256> {
300 let (lo, borrow) = sub_u128_borrow(self.lo(), rhs.lo(), false);
301 let (hi, underflow) = sub_u128_borrow(self.hi(), rhs.hi(), borrow);
302 if underflow {
303 None
304 } else {
305 Some(U256::new(lo, hi))
306 }
307 }
308
309 pub fn checked_mul(self, rhs: U256) -> Option<U256> {
310 if self.hi() != 0 && rhs.hi() != 0 {
311 return None;
312 }
313
314 let (prod_lo, prod_hi) = widening_mul_u128(self.lo(), rhs.lo());
315
316 let cross1 = if rhs.hi() != 0 {
317 let (c, overflow) = widening_mul_u128(self.lo(), rhs.hi());
318 if overflow != 0 {
319 return None;
320 }
321 c
322 } else {
323 0u128
324 };
325
326 let cross2 = if self.hi() != 0 {
327 let (c, overflow) = widening_mul_u128(self.hi(), rhs.lo());
328 if overflow != 0 {
329 return None;
330 }
331 c
332 } else {
333 0u128
334 };
335
336 let hi = prod_hi.checked_add(cross1)?;
337 let hi = hi.checked_add(cross2)?;
338
339 Some(U256::new(prod_lo, hi))
340 }
341
342 pub fn checked_div(self, rhs: U256) -> Option<U256> {
343 if rhs.is_zero() {
344 return None;
345 }
346 Some(div_rem_u256(self, rhs).0)
347 }
348
349 pub fn checked_rem(self, rhs: U256) -> Option<U256> {
350 if rhs.is_zero() {
351 return None;
352 }
353 Some(div_rem_u256(self, rhs).1)
354 }
355
356 pub fn overflowing_add(self, rhs: U256) -> (U256, bool) {
359 let (lo, carry) = add_u128_carry(self.lo(), rhs.lo(), false);
360 let (hi, overflow) = add_u128_carry(self.hi(), rhs.hi(), carry);
361 (U256::new(lo, hi), overflow)
362 }
363
364 pub fn overflowing_sub(self, rhs: U256) -> (U256, bool) {
365 let (lo, borrow) = sub_u128_borrow(self.lo(), rhs.lo(), false);
366 let (hi, underflow) = sub_u128_borrow(self.hi(), rhs.hi(), borrow);
367 (U256::new(lo, hi), underflow)
368 }
369
370 pub fn saturating_add(self, rhs: U256) -> U256 {
373 self.checked_add(rhs).unwrap_or(U256::MAX)
374 }
375
376 pub fn saturating_sub(self, rhs: U256) -> U256 {
377 self.checked_sub(rhs).unwrap_or(U256::ZERO)
378 }
379
380 pub fn shl(self, bits: u32) -> U256 {
383 if bits >= 256 {
384 return U256::ZERO;
385 }
386 if bits == 0 {
387 return self;
388 }
389 let lo = self.lo();
390 let hi = self.hi();
391 if bits >= 128 {
392 let s = bits - 128;
393 U256::new(0, lo << s)
394 } else {
395 let new_lo = lo << bits;
396 let new_hi = (hi << bits) | (lo >> (128 - bits));
397 U256::new(new_lo, new_hi)
398 }
399 }
400
401 pub fn shr(self, bits: u32) -> U256 {
402 if bits >= 256 {
403 return U256::ZERO;
404 }
405 if bits == 0 {
406 return self;
407 }
408 let lo = self.lo();
409 let hi = self.hi();
410 if bits >= 128 {
411 let s = bits - 128;
412 U256::new(hi >> s, 0)
413 } else {
414 let new_hi = hi >> bits;
415 let new_lo = (lo >> bits) | (hi << (128 - bits));
416 U256::new(new_lo, new_hi)
417 }
418 }
419
420 pub fn bitand(self, rhs: U256) -> U256 {
423 U256::new(self.lo() & rhs.lo(), self.hi() & rhs.hi())
424 }
425
426 pub fn bitor(self, rhs: U256) -> U256 {
427 U256::new(self.lo() | rhs.lo(), self.hi() | rhs.hi())
428 }
429}
430
431impl PartialOrd for U256 {
435 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
436 Some(self.cmp(other))
437 }
438}
439
440impl Ord for U256 {
441 fn cmp(&self, other: &Self) -> Ordering {
442 match self.hi().cmp(&other.hi()) {
443 Ordering::Equal => self.lo().cmp(&other.lo()),
444 ord => ord,
445 }
446 }
447}
448
449impl core::ops::Add for U256 {
453 type Output = Self;
454 #[inline]
455 fn add(self, rhs: Self) -> Self {
456 self.checked_add(rhs).expect("U256 add overflow")
457 }
458}
459
460impl core::ops::Sub for U256 {
461 type Output = Self;
462 #[inline]
463 fn sub(self, rhs: Self) -> Self {
464 self.checked_sub(rhs).expect("U256 sub underflow")
465 }
466}
467
468impl core::ops::Mul for U256 {
469 type Output = Self;
470 #[inline]
471 fn mul(self, rhs: Self) -> Self {
472 self.checked_mul(rhs).expect("U256 mul overflow")
473 }
474}
475
476impl core::ops::Div for U256 {
477 type Output = Self;
478 #[inline]
479 fn div(self, rhs: Self) -> Self {
480 self.checked_div(rhs).expect("U256 div by zero")
481 }
482}
483
484impl core::ops::Rem for U256 {
485 type Output = Self;
486 #[inline]
487 fn rem(self, rhs: Self) -> Self {
488 self.checked_rem(rhs).expect("U256 rem by zero")
489 }
490}
491
492impl core::ops::Shl<u32> for U256 {
493 type Output = Self;
494 #[inline]
495 fn shl(self, bits: u32) -> Self {
496 self.shl(bits)
497 }
498}
499
500impl core::ops::Shr<u32> for U256 {
501 type Output = Self;
502 #[inline]
503 fn shr(self, bits: u32) -> Self {
504 self.shr(bits)
505 }
506}
507
508impl core::ops::BitAnd for U256 {
509 type Output = Self;
510 #[inline]
511 fn bitand(self, rhs: Self) -> Self {
512 self.bitand(rhs)
513 }
514}
515
516impl core::ops::BitOr for U256 {
517 type Output = Self;
518 #[inline]
519 fn bitor(self, rhs: Self) -> Self {
520 self.bitor(rhs)
521 }
522}
523
524impl core::ops::AddAssign for U256 {
525 #[inline]
526 fn add_assign(&mut self, rhs: Self) {
527 *self = *self + rhs;
528 }
529}
530
531impl core::ops::SubAssign for U256 {
532 #[inline]
533 fn sub_assign(&mut self, rhs: Self) {
534 *self = *self - rhs;
535 }
536}
537
538#[cfg(kani)]
542#[repr(transparent)]
543#[derive(Clone, Copy, Debug, PartialEq, Eq)]
544pub struct I256([u128; 2]); #[cfg(kani)]
547impl I256 {
548 pub const ZERO: Self = Self([0, 0]);
549 pub const ONE: Self = Self([1, 0]);
550 pub const MINUS_ONE: Self = Self([u128::MAX, u128::MAX]); pub const MAX: Self = Self([u128::MAX, u128::MAX >> 1]);
553 pub const MIN: Self = Self([0, 1u128 << 127]);
555
556 pub fn from_i128(v: i128) -> Self {
557 let lo = v as u128;
559 let hi = if v < 0 { u128::MAX } else { 0 };
560 Self([lo, hi])
561 }
562
563 pub fn from_u128(v: u128) -> Self {
564 Self([v, 0])
568 }
569
570 pub fn try_into_i128(&self) -> Option<i128> {
571 let lo = self.0[0];
573 let hi = self.0[1];
574 let lo_sign_ext = if (lo as i128) < 0 { u128::MAX } else { 0 };
575 if hi == lo_sign_ext {
576 Some(lo as i128)
577 } else {
578 None
579 }
580 }
581
582 pub fn is_zero(&self) -> bool {
583 self.0[0] == 0 && self.0[1] == 0
584 }
585
586 pub fn is_negative(&self) -> bool {
587 (self.0[1] >> 127) != 0
588 }
589
590 pub fn is_positive(&self) -> bool {
591 !self.is_zero() && !self.is_negative()
592 }
593
594 pub fn signum(&self) -> i8 {
595 if self.is_zero() {
596 0
597 } else if self.is_negative() {
598 -1
599 } else {
600 1
601 }
602 }
603
604 pub fn abs_u256(self) -> U256 {
606 if self.is_negative() {
607 assert!(self != Self::MIN, "abs_u256 called on I256::MIN");
611 let inv_lo = !self.0[0];
612 let inv_hi = !self.0[1];
613 let (neg_lo, carry) = inv_lo.overflowing_add(1);
614 let neg_hi = inv_hi.wrapping_add(if carry { 1 } else { 0 });
615 U256::new(neg_lo, neg_hi)
616 } else {
617 U256::new(self.0[0], self.0[1])
618 }
619 }
620
621 pub fn checked_add(self, rhs: I256) -> Option<I256> {
624 let (lo, carry) = self.0[0].overflowing_add(rhs.0[0]);
625 let (hi, overflow1) = self.0[1].overflowing_add(rhs.0[1]);
626 let (hi, overflow2) = hi.overflowing_add(if carry { 1 } else { 0 });
627 let result = I256([lo, hi]);
628
629 let self_neg = self.is_negative();
632 let rhs_neg = rhs.is_negative();
633 let res_neg = result.is_negative();
634
635 if self_neg == rhs_neg && res_neg != self_neg {
639 None
640 } else {
641 Some(result)
642 }
643 }
644
645 pub fn checked_sub(self, rhs: I256) -> Option<I256> {
646 let neg_rhs = match rhs.checked_neg() {
647 Some(n) => n,
648 None => {
649 let (lo, borrow) = self.0[0].overflowing_sub(rhs.0[0]);
653 let (hi, underflow1) = self.0[1].overflowing_sub(rhs.0[1]);
654 let (hi, underflow2) = hi.overflowing_sub(if borrow { 1 } else { 0 });
655 let result = I256([lo, hi]);
656 let self_neg = self.is_negative();
661 let rhs_neg = true; let res_neg = result.is_negative();
663 if self_neg != rhs_neg && res_neg != self_neg {
666 return None;
667 }
668 return Some(result);
669 }
670 };
671 self.checked_add(neg_rhs)
672 }
673
674 pub fn checked_neg(self) -> Option<I256> {
675 if self == Self::MIN {
676 return None;
677 }
678 let inv_lo = !self.0[0];
679 let inv_hi = !self.0[1];
680 let (neg_lo, carry) = inv_lo.overflowing_add(1);
681 let neg_hi = inv_hi.wrapping_add(if carry { 1 } else { 0 });
682 Some(I256([neg_lo, neg_hi]))
683 }
684
685 pub fn saturating_add(self, rhs: I256) -> I256 {
686 match self.checked_add(rhs) {
687 Some(v) => v,
688 None => {
689 if rhs.is_negative() {
690 I256::MIN
691 } else {
692 I256::MAX
693 }
694 }
695 }
696 }
697
698 fn as_raw_u256(self) -> U256 {
700 U256::new(self.0[0], self.0[1])
701 }
702
703 pub fn from_raw_u256(v: U256) -> Self {
705 I256([v.lo(), v.hi()])
706 }
707}
708
709#[cfg(not(kani))]
713#[repr(C)]
714#[derive(Clone, Copy, Debug, PartialEq, Eq)]
715pub struct I256([u64; 4]); #[cfg(not(kani))]
718impl I256 {
719 pub const ZERO: Self = Self([0, 0, 0, 0]);
720 pub const ONE: Self = Self([1, 0, 0, 0]);
721 pub const MINUS_ONE: Self = Self([u64::MAX, u64::MAX, u64::MAX, u64::MAX]);
722 pub const MAX: Self = Self([u64::MAX, u64::MAX, u64::MAX, u64::MAX >> 1]);
723 pub const MIN: Self = Self([0, 0, 0, 1u64 << 63]);
724
725 pub fn from_i128(v: i128) -> Self {
726 let lo = v as u128;
727 let hi: u128 = if v < 0 { u128::MAX } else { 0 };
728 Self::from_lo_hi(lo, hi)
729 }
730
731 pub fn from_u128(v: u128) -> Self {
732 Self::from_lo_hi(v, 0)
733 }
734
735 pub fn try_into_i128(&self) -> Option<i128> {
736 let lo = self.lo_u128();
737 let hi = self.hi_u128();
738 let lo_sign_ext = if (lo as i128) < 0 { u128::MAX } else { 0 };
739 if hi == lo_sign_ext {
740 Some(lo as i128)
741 } else {
742 None
743 }
744 }
745
746 pub fn is_zero(&self) -> bool {
747 self.0[0] == 0 && self.0[1] == 0 && self.0[2] == 0 && self.0[3] == 0
748 }
749
750 pub fn is_negative(&self) -> bool {
751 (self.0[3] >> 63) != 0
752 }
753
754 pub fn is_positive(&self) -> bool {
755 !self.is_zero() && !self.is_negative()
756 }
757
758 pub fn signum(&self) -> i8 {
759 if self.is_zero() {
760 0
761 } else if self.is_negative() {
762 -1
763 } else {
764 1
765 }
766 }
767
768 pub fn abs_u256(self) -> U256 {
769 if self.is_negative() {
770 assert!(self != Self::MIN, "abs_u256 called on I256::MIN");
771 let lo = self.lo_u128();
772 let hi = self.hi_u128();
773 let inv_lo = !lo;
774 let inv_hi = !hi;
775 let (neg_lo, carry) = inv_lo.overflowing_add(1);
776 let neg_hi = inv_hi.wrapping_add(if carry { 1 } else { 0 });
777 U256::new(neg_lo, neg_hi)
778 } else {
779 U256::new(self.lo_u128(), self.hi_u128())
780 }
781 }
782
783 pub fn checked_add(self, rhs: I256) -> Option<I256> {
786 let s_lo = self.lo_u128();
787 let s_hi = self.hi_u128();
788 let r_lo = rhs.lo_u128();
789 let r_hi = rhs.hi_u128();
790 let (lo, carry) = s_lo.overflowing_add(r_lo);
791 let (hi, overflow1) = s_hi.overflowing_add(r_hi);
792 let (hi, overflow2) = hi.overflowing_add(if carry { 1 } else { 0 });
793 let result = I256::from_lo_hi(lo, hi);
794
795 let self_neg = self.is_negative();
796 let rhs_neg = rhs.is_negative();
797 let res_neg = result.is_negative();
798
799 if self_neg == rhs_neg && res_neg != self_neg {
800 None
801 } else {
802 Some(result)
803 }
804 }
805
806 pub fn checked_sub(self, rhs: I256) -> Option<I256> {
807 let neg_rhs = match rhs.checked_neg() {
808 Some(n) => n,
809 None => {
810 let s_lo = self.lo_u128();
811 let s_hi = self.hi_u128();
812 let r_lo = rhs.lo_u128();
813 let r_hi = rhs.hi_u128();
814 let (lo, borrow) = s_lo.overflowing_sub(r_lo);
815 let (hi, _underflow1) = s_hi.overflowing_sub(r_hi);
816 let (hi, _underflow2) = hi.overflowing_sub(if borrow { 1 } else { 0 });
817 let result = I256::from_lo_hi(lo, hi);
818 let self_neg = self.is_negative();
819 let res_neg = result.is_negative();
820 if self_neg != true && res_neg != self_neg {
821 return None;
822 }
823 return Some(result);
824 }
825 };
826 self.checked_add(neg_rhs)
827 }
828
829 pub fn checked_neg(self) -> Option<I256> {
830 if self == Self::MIN {
831 return None;
832 }
833 let lo = self.lo_u128();
834 let hi = self.hi_u128();
835 let inv_lo = !lo;
836 let inv_hi = !hi;
837 let (neg_lo, carry) = inv_lo.overflowing_add(1);
838 let neg_hi = inv_hi.wrapping_add(if carry { 1 } else { 0 });
839 Some(I256::from_lo_hi(neg_lo, neg_hi))
840 }
841
842 pub fn saturating_add(self, rhs: I256) -> I256 {
843 match self.checked_add(rhs) {
844 Some(v) => v,
845 None => {
846 if rhs.is_negative() {
847 I256::MIN
848 } else {
849 I256::MAX
850 }
851 }
852 }
853 }
854
855 fn lo_u128(&self) -> u128 {
857 (self.0[0] as u128) | ((self.0[1] as u128) << 64)
858 }
859
860 fn hi_u128(&self) -> u128 {
861 (self.0[2] as u128) | ((self.0[3] as u128) << 64)
862 }
863
864 fn from_lo_hi(lo: u128, hi: u128) -> Self {
865 Self([lo as u64, (lo >> 64) as u64, hi as u64, (hi >> 64) as u64])
866 }
867
868 fn as_raw_u256(self) -> U256 {
869 U256::new(self.lo_u128(), self.hi_u128())
870 }
871
872 pub fn from_raw_u256(v: U256) -> Self {
873 Self::from_lo_hi(v.lo(), v.hi())
874 }
875}
876
877impl PartialOrd for I256 {
881 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
882 Some(self.cmp(other))
883 }
884}
885
886impl Ord for I256 {
887 fn cmp(&self, other: &Self) -> Ordering {
888 let self_neg = self.is_negative();
889 let other_neg = other.is_negative();
890 match (self_neg, other_neg) {
891 (true, false) => Ordering::Less,
892 (false, true) => Ordering::Greater,
893 _ => {
894 self.as_raw_u256().cmp(&other.as_raw_u256())
897 }
898 }
899 }
900}
901
902impl core::ops::Add for I256 {
906 type Output = Self;
907 #[inline]
908 fn add(self, rhs: Self) -> Self {
909 self.checked_add(rhs).expect("I256 add overflow")
910 }
911}
912
913impl core::ops::Sub for I256 {
914 type Output = Self;
915 #[inline]
916 fn sub(self, rhs: Self) -> Self {
917 self.checked_sub(rhs).expect("I256 sub overflow")
918 }
919}
920
921impl core::ops::Neg for I256 {
922 type Output = Self;
923 #[inline]
924 fn neg(self) -> Self {
925 self.checked_neg().expect("I256 neg overflow (MIN)")
926 }
927}
928
929fn widening_mul_u128(a: u128, b: u128) -> (u128, u128) {
936 let a_lo = a as u64 as u128;
937 let a_hi = (a >> 64) as u64 as u128;
938 let b_lo = b as u64 as u128;
939 let b_hi = (b >> 64) as u64 as u128;
940
941 let ll = a_lo * b_lo; let lh = a_lo * b_hi; let hl = a_hi * b_lo; let hh = a_hi * b_hi; let (mid, mid_carry) = lh.overflowing_add(hl); let (lo, lo_carry) = ll.overflowing_add(mid << 64);
951 let hi = hh + (mid >> 64) + ((mid_carry as u128) << 64) + (lo_carry as u128);
952 (lo, hi)
955}
956
957#[cfg(not(kani))]
959fn add_u128_carry(a: u128, b: u128, carry_in: bool) -> (u128, bool) {
960 let (s1, c1) = a.overflowing_add(b);
961 let (s2, c2) = s1.overflowing_add(carry_in as u128);
962 (s2, c1 || c2)
963}
964
965#[cfg(not(kani))]
967fn sub_u128_borrow(a: u128, b: u128, borrow_in: bool) -> (u128, bool) {
968 let (d1, b1) = a.overflowing_sub(b);
969 let (d2, b2) = d1.overflowing_sub(borrow_in as u128);
970 (d2, b1 || b2)
971}
972
973fn leading_zeros_u256(v: U256) -> u32 {
979 if v.hi() != 0 {
980 v.hi().leading_zeros()
981 } else {
982 128 + v.lo().leading_zeros()
983 }
984}
985
986fn div_rem_u256(num: U256, den: U256) -> (U256, U256) {
988 if den.is_zero() {
989 panic!("U256 division by zero");
990 }
991 if num.is_zero() {
992 return (U256::ZERO, U256::ZERO);
993 }
994
995 if den > num {
997 return (U256::ZERO, num);
998 }
999
1000 if num.hi() == 0 && den.hi() == 0 {
1002 let q = num.lo() / den.lo();
1003 let r = num.lo() % den.lo();
1004 return (U256::from_u128(q), U256::from_u128(r));
1005 }
1006
1007 let shift = leading_zeros_u256(den) - leading_zeros_u256(num);
1009 let mut remainder = num;
1010 let mut quotient = U256::ZERO;
1011 let mut divisor = den.shl(shift);
1012
1013 let mut i = shift as i32;
1015 while i >= 0 {
1016 if remainder >= divisor {
1017 remainder = remainder.saturating_sub(divisor);
1018 quotient = quotient.bitor(U256::ONE.shl(i as u32));
1019 }
1020 divisor = divisor.shr(1);
1021 i -= 1;
1022 }
1023
1024 (quotient, remainder)
1025}
1026
1027#[derive(Clone, Copy, Debug, PartialEq, Eq)]
1034struct U512([u128; 4]);
1035
1036impl U512 {
1037 const ZERO: Self = Self([0, 0, 0, 0]);
1038
1039 fn is_zero(&self) -> bool {
1040 self.0[0] == 0 && self.0[1] == 0 && self.0[2] == 0 && self.0[3] == 0
1041 }
1042
1043 fn from_u256(v: U256) -> Self {
1044 Self([v.lo(), v.hi(), 0, 0])
1045 }
1046
1047 fn mul_u256(a: U256, b: U256) -> Self {
1049 let a0 = a.lo();
1051 let a1 = a.hi();
1052 let b0 = b.lo();
1053 let b1 = b.hi();
1054
1055 let (r0, c0) = widening_mul_u128(a0, b0);
1057
1058 let (x1, x2) = widening_mul_u128(a0, b1);
1060
1061 let (y1, y2) = widening_mul_u128(a1, b0);
1063
1064 let (z2, z3) = widening_mul_u128(a1, b1);
1066
1067 let (r1, carry1a) = c0.overflowing_add(x1);
1071 let (r1, carry1b) = r1.overflowing_add(y1);
1072 let carry1 = (carry1a as u128) + (carry1b as u128);
1073
1074 let (r2, carry2a) = x2.overflowing_add(y2);
1076 let (r2, carry2b) = r2.overflowing_add(z2);
1077 let (r2, carry2c) = r2.overflowing_add(carry1);
1078 let carry2 = (carry2a as u128) + (carry2b as u128) + (carry2c as u128);
1079
1080 let r3 = z3 + carry2; Self([r0, r1, r2, r3])
1084 }
1085
1086 fn cmp_u512(&self, other: &Self) -> Ordering {
1088 for i in (0..4).rev() {
1089 match self.0[i].cmp(&other.0[i]) {
1090 Ordering::Equal => continue,
1091 ord => return ord,
1092 }
1093 }
1094 Ordering::Equal
1095 }
1096
1097 fn shl_u512(self, bits: u32) -> Self {
1099 if bits >= 512 {
1100 return Self::ZERO;
1101 }
1102 if bits == 0 {
1103 return self;
1104 }
1105 let word_shift = (bits / 128) as usize;
1106 let bit_shift = bits % 128;
1107
1108 let mut result = [0u128; 4];
1109 for i in word_shift..4 {
1110 result[i] = self.0[i - word_shift] << bit_shift;
1111 if bit_shift > 0 && i > word_shift {
1112 result[i] |= self.0[i - word_shift - 1] >> (128 - bit_shift);
1113 }
1114 }
1115 Self(result)
1116 }
1117
1118 fn shr_u512(self, bits: u32) -> Self {
1120 if bits >= 512 {
1121 return Self::ZERO;
1122 }
1123 if bits == 0 {
1124 return self;
1125 }
1126 let word_shift = (bits / 128) as usize;
1127 let bit_shift = bits % 128;
1128
1129 let mut result = [0u128; 4];
1130 for i in 0..(4 - word_shift) {
1131 result[i] = self.0[i + word_shift] >> bit_shift;
1132 if bit_shift > 0 && (i + word_shift + 1) < 4 {
1133 result[i] |= self.0[i + word_shift + 1] << (128 - bit_shift);
1134 }
1135 }
1136 Self(result)
1137 }
1138
1139 fn sub_u512(self, rhs: Self) -> Self {
1141 let mut result = [0u128; 4];
1142 let mut borrow = false;
1143 for i in 0..4 {
1144 let (d1, b1) = self.0[i].overflowing_sub(rhs.0[i]);
1145 let (d2, b2) = d1.overflowing_sub(borrow as u128);
1146 result[i] = d2;
1147 borrow = b1 || b2;
1148 }
1149 Self(result)
1150 }
1151
1152 fn set_bit(self, bit: u32) -> Self {
1154 if bit >= 512 {
1155 return self;
1156 }
1157 let word = (bit / 128) as usize;
1158 let b = bit % 128;
1159 let mut result = self.0;
1160 result[word] |= 1u128 << b;
1161 Self(result)
1162 }
1163
1164 fn leading_zeros(&self) -> u32 {
1166 for i in (0..4).rev() {
1167 if self.0[i] != 0 {
1168 return (3 - i as u32) * 128 + self.0[i].leading_zeros();
1169 }
1170 }
1171 512
1172 }
1173
1174 fn try_into_u256(self) -> Option<U256> {
1176 if self.0[2] != 0 || self.0[3] != 0 {
1177 None
1178 } else {
1179 Some(U256::new(self.0[0], self.0[1]))
1180 }
1181 }
1182
1183 fn div_rem_by_u256(self, den: U256) -> (U256, U256) {
1186 match self.checked_div_rem_by_u256(den) {
1187 Some(result) => result,
1188 None => panic!("mul_div quotient must fit U256"),
1189 }
1190 }
1191
1192 fn checked_div_rem_by_u256(self, den: U256) -> Option<(U256, U256)> {
1194 assert!(!den.is_zero(), "U512 division by zero");
1195
1196 if self.is_zero() {
1197 return Some((U256::ZERO, U256::ZERO));
1198 }
1199
1200 let den_512 = U512::from_u256(den);
1201
1202 if self.cmp_u512(&den_512) == Ordering::Less {
1203 let r = self.try_into_u256().expect("remainder must fit U256");
1204 return Some((U256::ZERO, r));
1205 }
1206
1207 let num_lz = self.leading_zeros();
1208 let den_lz = den_512.leading_zeros();
1209
1210 if den_lz < num_lz {
1211 let r = self.try_into_u256().expect("remainder must fit U256");
1212 return Some((U256::ZERO, r));
1213 }
1214
1215 let shift = den_lz - num_lz;
1216 let mut remainder = self;
1217 let mut quotient = U512::ZERO;
1218 let mut divisor = den_512.shl_u512(shift);
1219
1220 let mut i = shift as i32;
1221 while i >= 0 {
1222 if remainder.cmp_u512(&divisor) != Ordering::Less {
1223 remainder = remainder.sub_u512(divisor);
1224 quotient = quotient.set_bit(i as u32);
1225 }
1226 divisor = divisor.shr_u512(1);
1227 i -= 1;
1228 }
1229
1230 let q = quotient.try_into_u256()?;
1231 let r = remainder.try_into_u256().expect("remainder must fit U256");
1232 Some((q, r))
1233 }
1234}
1235
1236pub fn floor_div_signed_conservative(n: I256, d: U256) -> I256 {
1245 assert!(
1246 !d.is_zero(),
1247 "floor_div_signed_conservative: zero denominator"
1248 );
1249
1250 if n.is_zero() {
1251 return I256::ZERO;
1252 }
1253
1254 let negative = n.is_negative();
1255
1256 if !negative {
1259 let n_u = n.abs_u256();
1261 let (q, _r) = div_rem_u256(n_u, d);
1262 I256::from_raw_u256(q)
1264 } else {
1265 let raw = n.as_raw_u256();
1273 let inv = U256::new(!raw.lo(), !raw.hi());
1275 let abs_n = inv.checked_add(U256::ONE).expect("abs of negative I256");
1276
1277 let (q, r) = div_rem_u256(abs_n, d);
1278
1279 let q_final = if r.is_zero() {
1281 q
1282 } else {
1283 q.checked_add(U256::ONE)
1284 .expect("floor_div quotient overflow")
1285 };
1286
1287 if q_final.is_zero() {
1290 I256::ZERO
1291 } else {
1292 let qi = I256::from_raw_u256(q_final);
1293 qi.checked_neg().expect("floor_div result out of range")
1294 }
1295 }
1296}
1297
1298pub fn floor_div_signed_conservative_i128(n: i128, d: u128) -> i128 {
1302 assert!(
1303 d != 0,
1304 "floor_div_signed_conservative_i128: zero denominator"
1305 );
1306
1307 if n == 0 {
1308 return 0;
1309 }
1310
1311 if n > 0 {
1312 (n as u128 / d) as i128
1314 } else {
1315 let abs_n = n.unsigned_abs();
1317 let q = abs_n / d;
1318 let r = abs_n % d;
1319 let q_final = if r != 0 { q + 1 } else { q };
1320 assert!(
1321 q_final <= i128::MAX as u128,
1322 "floor_div_signed_conservative_i128: result out of range"
1323 );
1324 -(q_final as i128)
1325 }
1326}
1327
1328pub fn ceil_div_positive_checked(n: U256, d: U256) -> U256 {
1332 assert!(!d.is_zero(), "ceil_div_positive_checked: zero denominator");
1333 let (q, r) = div_rem_u256(n, d);
1334 if r.is_zero() {
1335 q
1336 } else {
1337 q.checked_add(U256::ONE).expect("ceil_div overflow")
1338 }
1339}
1340
1341pub fn mul_div_floor_u256(a: U256, b: U256, d: U256) -> U256 {
1344 assert!(!d.is_zero(), "mul_div_floor_u256: zero denominator");
1345 let product = U512::mul_u256(a, b);
1346 let (q, _r) = product.div_rem_by_u256(d);
1347 q
1348}
1349
1350pub fn mul_div_floor_u256_with_rem(a: U256, b: U256, d: U256) -> (U256, U256) {
1353 assert!(
1354 !d.is_zero(),
1355 "mul_div_floor_u256_with_rem: zero denominator"
1356 );
1357 let product = U512::mul_u256(a, b);
1358 product.div_rem_by_u256(d)
1359}
1360
1361pub fn mul_div_ceil_u256(a: U256, b: U256, d: U256) -> U256 {
1364 assert!(!d.is_zero(), "mul_div_ceil_u256: zero denominator");
1365 let product = U512::mul_u256(a, b);
1366 let (q, r) = product.div_rem_by_u256(d);
1367 if r.is_zero() {
1368 q
1369 } else {
1370 q.checked_add(U256::ONE).expect("mul_div_ceil overflow")
1371 }
1372}
1373
1374#[allow(dead_code)]
1377pub fn checked_mul_div_ceil_u256(a: U256, b: U256, d: U256) -> Option<U256> {
1378 if d.is_zero() {
1379 return None;
1380 }
1381 let product = U512::mul_u256(a, b);
1382 let (q, r) = product.checked_div_rem_by_u256(d)?;
1383 if r.is_zero() {
1384 Some(q)
1385 } else {
1386 q.checked_add(U256::ONE)
1387 }
1388}
1389
1390pub fn saturating_mul_u256_u64(a: U256, b: u64) -> U256 {
1392 let rhs = U256::from_u64(b);
1393 a.checked_mul(rhs).unwrap_or(U256::MAX)
1394}
1395
1396pub fn fee_debt_u128_checked(fee_credits: i128) -> u128 {
1400 if fee_credits < 0 {
1401 fee_credits.unsigned_abs()
1404 } else {
1405 0
1406 }
1407}
1408
1409pub fn wide_signed_mul_div_floor(abs_basis: U256, k_diff: I256, denominator: U256) -> I256 {
1417 assert!(
1418 !denominator.is_zero(),
1419 "wide_signed_mul_div_floor: zero denominator"
1420 );
1421
1422 if k_diff.is_zero() || abs_basis.is_zero() {
1423 return I256::ZERO;
1424 }
1425
1426 let negative = k_diff.is_negative();
1427 let abs_k = if negative {
1428 assert!(
1429 k_diff != I256::MIN,
1430 "wide_signed_mul_div_floor: k_diff == I256::MIN"
1431 );
1432 k_diff.abs_u256()
1433 } else {
1434 k_diff.abs_u256()
1435 };
1436
1437 let product = U512::mul_u256(abs_basis, abs_k);
1439 let (q, r) = product.div_rem_by_u256(denominator);
1440
1441 if !negative {
1442 I256::from_raw_u256(q)
1444 } else {
1445 let q_final = if r.is_zero() {
1447 q
1448 } else {
1449 q.checked_add(U256::ONE)
1450 .expect("wide_signed_mul_div_floor quotient overflow")
1451 };
1452 if q_final.is_zero() {
1453 I256::ZERO
1454 } else {
1455 let qi = I256::from_raw_u256(q_final);
1456 qi.checked_neg()
1457 .expect("wide_signed_mul_div_floor result out of I256 range")
1458 }
1459 }
1460}
1461
1462impl I256 {
1469 }
1472
1473pub fn mul_div_floor_u128(a: u128, b: u128, d: u128) -> u128 {
1479 assert!(d > 0, "mul_div_floor_u128: division by zero");
1480 let p = a.checked_mul(b).expect("mul_div_floor_u128: a*b overflow");
1481 p / d
1482}
1483
1484pub fn mul_div_ceil_u128(a: u128, b: u128, d: u128) -> u128 {
1486 assert!(d > 0, "mul_div_ceil_u128: division by zero");
1487 let p = a.checked_mul(b).expect("mul_div_ceil_u128: a*b overflow");
1488 let q = p / d;
1489 if p % d != 0 {
1490 q + 1
1491 } else {
1492 q
1493 }
1494}
1495
1496pub fn wide_mul_div_floor_u128(a: u128, b: u128, d: u128) -> u128 {
1499 assert!(d > 0, "wide_mul_div_floor_u128: division by zero");
1500 let result = mul_div_floor_u256(U256::from_u128(a), U256::from_u128(b), U256::from_u128(d));
1501 result
1502 .try_into_u128()
1503 .expect("wide_mul_div_floor_u128: result exceeds u128")
1504}
1505
1506pub fn wide_signed_mul_div_floor_from_k_pair(
1509 abs_basis: u128,
1510 k_then: i128,
1511 k_now: i128,
1512 den: u128,
1513) -> i128 {
1514 assert!(den > 0, "wide_signed_mul_div_floor_from_k_pair: den == 0");
1515 let k_now_wide = I256::from_i128(k_now);
1517 let k_then_wide = I256::from_i128(k_then);
1518 let d = k_now_wide
1519 .checked_sub(k_then_wide)
1520 .expect("K-diff overflow in wide");
1521 if d.is_zero() || abs_basis == 0 {
1522 return 0i128;
1523 }
1524 let abs_d = d.abs_u256();
1525 let abs_basis_u256 = U256::from_u128(abs_basis);
1526 let den_u256 = U256::from_u128(den);
1527 let p = abs_basis_u256
1529 .checked_mul(abs_d)
1530 .expect("wide product overflow");
1531 let (q, rem) = div_rem_u256(p, den_u256);
1532 if d.is_negative() {
1533 let mag = if !rem.is_zero() {
1535 q.checked_add(U256::ONE).expect("mag overflow")
1536 } else {
1537 q
1538 };
1539 let mag_u128 = mag.try_into_u128().expect("mag exceeds u128");
1540 assert!(
1541 mag_u128 <= i128::MAX as u128,
1542 "wide_signed_mul_div_floor_from_k_pair: mag > i128::MAX"
1543 );
1544 -(mag_u128 as i128)
1545 } else {
1546 let q_u128 = q.try_into_u128().expect("quotient exceeds u128");
1547 assert!(
1548 q_u128 <= i128::MAX as u128,
1549 "wide_signed_mul_div_floor_from_k_pair: q > i128::MAX"
1550 );
1551 q_u128 as i128
1552 }
1553}
1554
1555#[derive(Clone, Copy, Debug, PartialEq, Eq)]
1557pub struct OverI128Magnitude;
1558
1559pub fn wide_mul_div_ceil_u128_or_over_i128max(
1562 a: u128,
1563 b: u128,
1564 d: u128,
1565) -> core::result::Result<u128, OverI128Magnitude> {
1566 assert!(
1567 d > 0,
1568 "wide_mul_div_ceil_u128_or_over_i128max: division by zero"
1569 );
1570 let result = mul_div_ceil_u256(U256::from_u128(a), U256::from_u128(b), U256::from_u128(d));
1571 match result.try_into_u128() {
1572 Some(v) if v <= i128::MAX as u128 => Ok(v),
1573 _ => Err(OverI128Magnitude),
1574 }
1575}
1576
1577pub fn saturating_mul_u128_u64(a: u128, b: u64) -> u128 {
1579 if a == 0 || b == 0 {
1580 return 0;
1581 }
1582 let b128 = b as u128;
1583 a.checked_mul(b128).unwrap_or(u128::MAX)
1584}
1585
1586#[cfg(test)]
1590mod tests {
1591 use super::*;
1592
1593 #[test]
1595 fn test_u256_zero_one_max() {
1596 assert!(U256::ZERO.is_zero());
1597 assert!(!U256::ONE.is_zero());
1598 assert_eq!(U256::ONE.lo(), 1);
1599 assert_eq!(U256::ONE.hi(), 0);
1600 assert_eq!(U256::MAX.lo(), u128::MAX);
1601 assert_eq!(U256::MAX.hi(), u128::MAX);
1602 }
1603
1604 #[test]
1605 fn test_u256_from_u128() {
1606 let v = U256::from_u128(42);
1607 assert_eq!(v.lo(), 42);
1608 assert_eq!(v.hi(), 0);
1609 assert_eq!(v.try_into_u128(), Some(42));
1610 }
1611
1612 #[test]
1613 fn test_u256_try_into_u128_overflow() {
1614 let v = U256::new(1, 1);
1615 assert_eq!(v.try_into_u128(), None);
1616 }
1617
1618 #[test]
1620 fn test_u256_checked_add() {
1621 let a = U256::from_u128(100);
1622 let b = U256::from_u128(200);
1623 assert_eq!(a.checked_add(b), Some(U256::from_u128(300)));
1624 }
1625
1626 #[test]
1627 fn test_u256_add_with_carry() {
1628 let a = U256::new(u128::MAX, 0);
1629 let b = U256::new(1, 0);
1630 let c = a.checked_add(b).unwrap();
1631 assert_eq!(c.lo(), 0);
1632 assert_eq!(c.hi(), 1);
1633 }
1634
1635 #[test]
1636 fn test_u256_add_overflow() {
1637 assert_eq!(U256::MAX.checked_add(U256::ONE), None);
1638 }
1639
1640 #[test]
1641 fn test_u256_saturating_add() {
1642 assert_eq!(U256::MAX.saturating_add(U256::ONE), U256::MAX);
1643 }
1644
1645 #[test]
1647 fn test_u256_checked_sub() {
1648 let a = U256::from_u128(300);
1649 let b = U256::from_u128(100);
1650 assert_eq!(a.checked_sub(b), Some(U256::from_u128(200)));
1651 }
1652
1653 #[test]
1654 fn test_u256_sub_underflow() {
1655 let a = U256::from_u128(1);
1656 let b = U256::from_u128(2);
1657 assert_eq!(a.checked_sub(b), None);
1658 }
1659
1660 #[test]
1662 fn test_u256_checked_mul_small() {
1663 let a = U256::from_u128(1_000_000);
1664 let b = U256::from_u128(1_000_000);
1665 assert_eq!(a.checked_mul(b), Some(U256::from_u128(1_000_000_000_000)));
1666 }
1667
1668 #[test]
1669 fn test_u256_checked_mul_cross() {
1670 let a = U256::new(0, 1); let b = U256::from_u128(2);
1673 let c = a.checked_mul(b).unwrap();
1674 assert_eq!(c.lo(), 0);
1675 assert_eq!(c.hi(), 2);
1676 }
1677
1678 #[test]
1679 fn test_u256_mul_overflow() {
1680 let a = U256::new(0, 1); let b = U256::new(0, 1); assert_eq!(a.checked_mul(b), None);
1684 }
1685
1686 #[test]
1688 fn test_u256_div_basic() {
1689 let a = U256::from_u128(1000);
1690 let b = U256::from_u128(3);
1691 assert_eq!(a.checked_div(b), Some(U256::from_u128(333)));
1692 assert_eq!(a.checked_rem(b), Some(U256::from_u128(1)));
1693 }
1694
1695 #[test]
1696 fn test_u256_div_large() {
1697 let a = U256::new(0, 4); let b = U256::from_u128(2);
1700 let q = a.checked_div(b).unwrap();
1701 assert_eq!(q, U256::new(0, 2)); }
1703
1704 #[test]
1705 fn test_u256_div_by_zero() {
1706 assert_eq!(U256::ONE.checked_div(U256::ZERO), None);
1707 }
1708
1709 #[test]
1711 fn test_u256_ordering() {
1712 assert!(U256::ZERO < U256::ONE);
1713 assert!(U256::ONE < U256::MAX);
1714 assert!(U256::new(0, 1) > U256::new(u128::MAX, 0));
1715 }
1716
1717 #[test]
1719 fn test_u256_shl_shr() {
1720 let a = U256::ONE;
1721 let b = a.shl(128);
1722 assert_eq!(b, U256::new(0, 1));
1723 let c = b.shr(128);
1724 assert_eq!(c, U256::ONE);
1725
1726 assert_eq!(U256::MAX.shl(256), U256::ZERO);
1728 assert_eq!(U256::MAX.shr(256), U256::ZERO);
1729 }
1730
1731 #[test]
1733 fn test_u256_bitand_bitor() {
1734 let a = U256::new(0xFF, 0xFF00);
1735 let b = U256::new(0x0F, 0xFF00);
1736 assert_eq!(a.bitand(b), U256::new(0x0F, 0xFF00));
1737 assert_eq!(a.bitor(b), U256::new(0xFF, 0xFF00));
1738 }
1739
1740 #[test]
1742 fn test_i256_zero_one_minusone() {
1743 assert!(I256::ZERO.is_zero());
1744 assert!(I256::ONE.is_positive());
1745 assert!(I256::MINUS_ONE.is_negative());
1746 assert_eq!(I256::ONE.signum(), 1);
1747 assert_eq!(I256::ZERO.signum(), 0);
1748 assert_eq!(I256::MINUS_ONE.signum(), -1);
1749 }
1750
1751 #[test]
1752 fn test_i256_from_i128() {
1753 let v = I256::from_i128(-42);
1754 assert!(v.is_negative());
1755 assert_eq!(v.try_into_i128(), Some(-42));
1756
1757 let v2 = I256::from_i128(i128::MAX);
1758 assert_eq!(v2.try_into_i128(), Some(i128::MAX));
1759
1760 let v3 = I256::from_i128(i128::MIN);
1761 assert_eq!(v3.try_into_i128(), Some(i128::MIN));
1762 }
1763
1764 #[test]
1766 fn test_i256_add() {
1767 let a = I256::from_i128(100);
1768 let b = I256::from_i128(-50);
1769 let c = a.checked_add(b).unwrap();
1770 assert_eq!(c.try_into_i128(), Some(50));
1771 }
1772
1773 #[test]
1774 fn test_i256_sub() {
1775 let a = I256::from_i128(10);
1776 let b = I256::from_i128(20);
1777 let c = a.checked_sub(b).unwrap();
1778 assert_eq!(c.try_into_i128(), Some(-10));
1779 }
1780
1781 #[test]
1782 fn test_i256_neg() {
1783 let a = I256::from_i128(42);
1784 let b = a.checked_neg().unwrap();
1785 assert_eq!(b.try_into_i128(), Some(-42));
1786
1787 assert_eq!(I256::MIN.checked_neg(), None);
1789 }
1790
1791 #[test]
1792 fn test_i256_overflow() {
1793 assert_eq!(I256::MAX.checked_add(I256::ONE), None);
1795 assert_eq!(I256::MIN.checked_sub(I256::ONE), None);
1797 }
1798
1799 #[test]
1800 fn test_i256_abs_u256() {
1801 let v = I256::from_i128(-100);
1802 let a = v.abs_u256();
1803 assert_eq!(a, U256::from_u128(100));
1804 }
1805
1806 #[test]
1808 fn test_i256_ordering() {
1809 assert!(I256::MIN < I256::MINUS_ONE);
1810 assert!(I256::MINUS_ONE < I256::ZERO);
1811 assert!(I256::ZERO < I256::ONE);
1812 assert!(I256::ONE < I256::MAX);
1813 }
1814
1815 #[test]
1817 fn test_floor_div_positive() {
1818 let n = I256::from_i128(7);
1820 let d = U256::from_u128(3);
1821 let q = floor_div_signed_conservative(n, d);
1822 assert_eq!(q.try_into_i128(), Some(2));
1823 }
1824
1825 #[test]
1826 fn test_floor_div_negative_exact() {
1827 let n = I256::from_i128(-6);
1829 let d = U256::from_u128(3);
1830 let q = floor_div_signed_conservative(n, d);
1831 assert_eq!(q.try_into_i128(), Some(-2));
1832 }
1833
1834 #[test]
1835 fn test_floor_div_negative_remainder() {
1836 let n = I256::from_i128(-7);
1838 let d = U256::from_u128(3);
1839 let q = floor_div_signed_conservative(n, d);
1840 assert_eq!(q.try_into_i128(), Some(-3));
1841 }
1842
1843 #[test]
1845 fn test_mul_div_floor() {
1846 let a = U256::from_u128(10);
1848 let b = U256::from_u128(20);
1849 let d = U256::from_u128(3);
1850 assert_eq!(mul_div_floor_u256(a, b, d), U256::from_u128(66));
1851 }
1852
1853 #[test]
1854 fn test_mul_div_ceil() {
1855 let a = U256::from_u128(10);
1857 let b = U256::from_u128(20);
1858 let d = U256::from_u128(3);
1859 assert_eq!(mul_div_ceil_u256(a, b, d), U256::from_u128(67));
1860 }
1861
1862 #[test]
1863 fn test_mul_div_large() {
1864 let big = U256::ONE.shl(200);
1867 assert_eq!(mul_div_floor_u256(big, big, big), big);
1868 }
1869
1870 #[test]
1871 fn test_mul_div_exact() {
1872 let a = U256::from_u128(6);
1874 let b = U256::from_u128(7);
1875 let d = U256::from_u128(42);
1876 assert_eq!(mul_div_floor_u256(a, b, d), U256::ONE);
1877 assert_eq!(mul_div_ceil_u256(a, b, d), U256::ONE);
1878 }
1879
1880 #[test]
1882 fn test_ceil_div_positive() {
1883 assert_eq!(
1885 ceil_div_positive_checked(U256::from_u128(7), U256::from_u128(3)),
1886 U256::from_u128(3)
1887 );
1888 assert_eq!(
1890 ceil_div_positive_checked(U256::from_u128(6), U256::from_u128(3)),
1891 U256::from_u128(2)
1892 );
1893 }
1894
1895 #[test]
1897 fn test_saturating_mul_u256_u64() {
1898 let a = U256::from_u128(100);
1899 assert_eq!(saturating_mul_u256_u64(a, 5), U256::from_u128(500));
1900 assert_eq!(saturating_mul_u256_u64(U256::MAX, 2), U256::MAX);
1902 }
1903
1904 #[test]
1906 fn test_fee_debt() {
1907 assert_eq!(fee_debt_u128_checked(-100), 100);
1908 assert_eq!(fee_debt_u128_checked(100), 0);
1909 assert_eq!(fee_debt_u128_checked(0), 0);
1910 assert_eq!(fee_debt_u128_checked(i128::MIN), 1u128 << 127);
1911 }
1912
1913 #[test]
1915 fn test_wide_signed_mul_div_floor_positive() {
1916 let abs_basis = U256::from_u128(10);
1918 let k_diff = I256::from_i128(20);
1919 let denom = U256::from_u128(3);
1920 let result = wide_signed_mul_div_floor(abs_basis, k_diff, denom);
1921 assert_eq!(result.try_into_i128(), Some(66));
1922 }
1923
1924 #[test]
1925 fn test_wide_signed_mul_div_floor_negative() {
1926 let abs_basis = U256::from_u128(10);
1928 let k_diff = I256::from_i128(-7);
1929 let denom = U256::from_u128(3);
1930 let result = wide_signed_mul_div_floor(abs_basis, k_diff, denom);
1931 assert_eq!(result.try_into_i128(), Some(-24));
1932 }
1933
1934 #[test]
1935 fn test_wide_signed_mul_div_floor_exact_negative() {
1936 let abs_basis = U256::from_u128(10);
1938 let k_diff = I256::from_i128(-6);
1939 let denom = U256::from_u128(3);
1940 let result = wide_signed_mul_div_floor(abs_basis, k_diff, denom);
1941 assert_eq!(result.try_into_i128(), Some(-20));
1942 }
1943
1944 #[test]
1945 fn test_wide_signed_mul_div_floor_zero() {
1946 let abs_basis = U256::from_u128(10);
1947 let k_diff = I256::ZERO;
1948 let denom = U256::from_u128(3);
1949 let result = wide_signed_mul_div_floor(abs_basis, k_diff, denom);
1950 assert_eq!(result, I256::ZERO);
1951 }
1952
1953 #[test]
1955 #[should_panic(expected = "U256 add overflow")]
1956 fn test_u256_add_op_panic() {
1957 let _ = U256::MAX + U256::ONE;
1958 }
1959
1960 #[test]
1961 #[should_panic(expected = "U256 sub underflow")]
1962 fn test_u256_sub_op_panic() {
1963 let _ = U256::ZERO - U256::ONE;
1964 }
1965
1966 #[test]
1967 fn test_u256_overflowing() {
1968 let (val, overflow) = U256::MAX.overflowing_add(U256::ONE);
1969 assert!(overflow);
1970 assert_eq!(val, U256::ZERO);
1971
1972 let (val, underflow) = U256::ZERO.overflowing_sub(U256::ONE);
1973 assert!(underflow);
1974 assert_eq!(val, U256::MAX);
1975 }
1976
1977 #[test]
1979 fn test_i256_from_u128() {
1980 let v = I256::from_u128(100);
1981 assert!(v.is_positive());
1982 assert_eq!(v.try_into_i128(), Some(100));
1983 }
1984
1985 #[test]
1987 fn test_i256_sub_min() {
1988 assert_eq!(I256::ZERO.checked_sub(I256::MIN), None);
1990 }
1991
1992 #[test]
1994 fn test_u256_assign_ops() {
1995 let mut v = U256::from_u128(10);
1996 v += U256::from_u128(5);
1997 assert_eq!(v, U256::from_u128(15));
1998 v -= U256::from_u128(3);
1999 assert_eq!(v, U256::from_u128(12));
2000 }
2001
2002 #[test]
2004 fn test_i256_saturating_add() {
2005 assert_eq!(I256::MAX.saturating_add(I256::ONE), I256::MAX);
2006 assert_eq!(I256::MIN.saturating_add(I256::MINUS_ONE), I256::MIN);
2007 }
2008
2009 #[test]
2011 fn test_widening_mul_u128() {
2012 let (lo, hi) = widening_mul_u128(u128::MAX, u128::MAX);
2013 assert_eq!(lo, 1);
2016 assert_eq!(hi, u128::MAX - 1);
2017 }
2018
2019 #[test]
2021 fn test_mul_div_max() {
2022 assert_eq!(
2024 mul_div_floor_u256(U256::MAX, U256::ONE, U256::ONE),
2025 U256::MAX
2026 );
2027 assert_eq!(
2029 mul_div_floor_u256(U256::ONE, U256::ONE, U256::ONE),
2030 U256::ONE
2031 );
2032 }
2033}