1use std::mem::MaybeUninit;
2use std::str::FromStr;
3
4use crate::cell::{CellBuilder, CellContext, CellSlice, ExactSize, Load, Size, Store};
5use crate::error::Error;
6use crate::util::unlikely;
7
8#[derive(Debug, Default, Clone, Copy, Hash, PartialEq, Eq)]
12#[repr(transparent)]
13pub struct VarUint248([u128; 2]);
14
15impl VarUint248 {
16 pub const ZERO: Self = Self([0, 0]);
18
19 pub const ONE: Self = Self([1, 0]);
21
22 pub const MIN: Self = Self::new(1);
24
25 pub const MAX: Self = Self::from_words(u128::MAX >> 8, u128::MAX);
27
28 pub const LEN_BITS: u16 = 5;
30
31 pub const MAX_BITS: u16 = Self::LEN_BITS + 31 * 8;
33
34 #[inline]
36 pub const fn new(value: u128) -> Self {
37 Self::from_words(0, value)
38 }
39
40 #[inline]
42 pub const fn from_words(hi: u128, lo: u128) -> Self {
43 #[cfg(target_endian = "little")]
44 {
45 Self([lo, hi])
46 }
47 #[cfg(target_endian = "big")]
48 {
49 Self([hi, lo])
50 }
51 }
52
53 #[inline]
55 pub const fn into_words(self) -> (u128, u128) {
56 #[cfg(target_endian = "little")]
57 {
58 (self.0[1], self.0[0])
59 }
60 #[cfg(target_endian = "big")]
61 {
62 (self.0[0], self.0[1])
63 }
64 }
65
66 pub fn from_str_radix(src: &str, radix: u32) -> Result<Self, std::num::ParseIntError> {
68 from_str_radix(src, radix, None)
69 }
70
71 #[inline]
73 pub const fn is_zero(&self) -> bool {
74 self.0[0] == 0 && self.0[1] == 0
75 }
76
77 #[inline]
79 pub const fn is_valid(&self) -> bool {
80 *self.high() <= (u128::MAX >> 8)
81 }
82
83 pub const fn bit_len(&self) -> Option<u16> {
86 let bytes = (32 - self.leading_zeros() / 8) as u8;
87 if unlikely(bytes > 31) {
88 None
89 } else {
90 Some(Self::LEN_BITS + bytes as u16 * 8)
91 }
92 }
93
94 pub const fn leading_zeros(&self) -> u32 {
96 let (hi, lo) = self.into_words();
97 if hi == 0 {
98 128 + lo.leading_zeros()
99 } else {
100 hi.leading_zeros()
101 }
102 }
103
104 #[must_use]
107 pub const fn saturating_add(self, rhs: &Self) -> Self {
108 match self.checked_add(rhs) {
109 Some(value) => value,
110 None => Self::MAX,
111 }
112 }
113
114 #[must_use]
117 pub const fn saturating_sub(self, rhs: &Self) -> Self {
118 let (lo, carry_lo) = self.low().overflowing_sub(*rhs.low());
119 let (hi, carry_c) = self.high().overflowing_sub(carry_lo as _);
120 let (hi, carry_hi) = hi.overflowing_sub(*rhs.high());
121
122 if carry_c || carry_hi {
123 return Self::ZERO;
124 }
125
126 let res = Self::from_words(hi, lo);
127 if res.is_valid() { res } else { Self::MAX }
128 }
129
130 #[must_use]
133 pub fn saturating_mul(self, rhs: &Self) -> Self {
134 match self.checked_mul(rhs) {
135 Some(value) => value,
136 None => Self::MAX,
137 }
138 }
139
140 #[must_use]
143 pub const fn checked_add(&self, rhs: &Self) -> Option<Self> {
144 let (lo, carry_lo) = self.low().overflowing_add(*rhs.low());
145 let (hi, carry_c) = self.high().overflowing_add(carry_lo as _);
146 let (hi, carry_hi) = hi.overflowing_add(*rhs.high());
147
148 if carry_c || carry_hi {
149 return None;
150 }
151
152 let res = Self::from_words(hi, lo);
153 if res.is_valid() { Some(res) } else { None }
154 }
155
156 #[must_use]
159 pub const fn checked_sub(&self, rhs: &Self) -> Option<Self> {
160 let (lo, carry_lo) = self.low().overflowing_sub(*rhs.low());
161 let (hi, carry_c) = self.high().overflowing_sub(carry_lo as _);
162 let (hi, carry_hi) = hi.overflowing_sub(*rhs.high());
163
164 if carry_c || carry_hi {
165 return None;
166 }
167
168 let res = Self::from_words(hi, lo);
169 if res.is_valid() { Some(res) } else { None }
170 }
171
172 #[must_use]
175 pub fn checked_mul(&self, rhs: &Self) -> Option<Self> {
176 let mut res = umulddi3(self.low(), rhs.low());
177
178 let (hi_lo, overflow_hi_lo) = self.high().overflowing_mul(*rhs.low());
179 let (lo_hi, overflow_lo_hi) = self.low().overflowing_mul(*rhs.high());
180 let (hi, overflow_hi) = hi_lo.overflowing_add(lo_hi);
181 let (high, overflow_high) = res.high().overflowing_add(hi);
182 *res.high_mut() = high;
183
184 let overflow_hi_hi = (*self.high() != 0) & (*rhs.high() != 0);
185
186 if overflow_hi_lo
187 || overflow_lo_hi
188 || overflow_hi
189 || overflow_high
190 || overflow_hi_hi
191 || !self.is_valid()
192 {
193 None
194 } else {
195 Some(res)
196 }
197 }
198
199 pub const fn low(&self) -> &u128 {
201 &self.0[0]
202 }
203
204 pub const fn high(&self) -> &u128 {
206 &self.0[1]
207 }
208
209 pub fn low_mut(&mut self) -> &mut u128 {
211 &mut self.0[0]
212 }
213
214 pub fn high_mut(&mut self) -> &mut u128 {
216 &mut self.0[1]
217 }
218
219 #[inline]
221 pub const fn as_isize(self) -> isize {
222 let (_, lo) = self.into_words();
223 lo as _
224 }
225
226 #[inline]
228 pub const fn as_usize(self) -> usize {
229 let (_, lo) = self.into_words();
230 lo as _
231 }
232}
233
234macro_rules! impl_from {
235 ($($ty:ty),*$(,)?) => {
236 $(impl From<$ty> for VarUint248 {
237 #[inline]
238 fn from(value: $ty) -> Self {
239 Self::new(value as _)
240 }
241 })*
242 };
243}
244
245impl_from! { u8, u16, u32, u64, u128, usize }
246
247#[cfg(feature = "bigint")]
248impl From<VarUint248> for num_bigint::BigInt {
249 #[inline]
250 fn from(value: VarUint248) -> Self {
251 num_bigint::BigUint::from(value).into()
252 }
253}
254
255#[cfg(feature = "bigint")]
256impl From<VarUint248> for num_bigint::BigUint {
257 fn from(value: VarUint248) -> Self {
258 let (high, low) = value.into_words();
259 if high == 0 {
260 return Self::from(low);
261 }
262
263 let mut res = Self::from(high);
264 res <<= 128;
265 res += low;
266 res
267 }
268}
269
270impl ExactSize for VarUint248 {
271 #[inline]
272 fn exact_size(&self) -> Size {
273 Size {
274 bits: self.bit_len().unwrap_or_default(),
275 refs: 0,
276 }
277 }
278}
279
280impl PartialEq<u128> for VarUint248 {
281 fn eq(&self, other: &u128) -> bool {
282 self.into_words() == (0, *other)
283 }
284}
285
286impl Ord for VarUint248 {
287 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
288 self.into_words().cmp(&other.into_words())
289 }
290}
291
292impl PartialOrd for VarUint248 {
293 #[inline]
294 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
295 Some(self.cmp(other))
296 }
297}
298
299impl PartialOrd<u128> for VarUint248 {
300 #[inline]
301 fn partial_cmp(&self, other: &u128) -> Option<std::cmp::Ordering> {
302 Some(self.into_words().cmp(&(0, *other)))
303 }
304}
305
306impl Store for VarUint248 {
307 fn store_into(&self, builder: &mut CellBuilder, _: &dyn CellContext) -> Result<(), Error> {
308 let bytes = (32 - self.leading_zeros() / 8) as u8;
309 let mut bits = bytes as u16 * 8;
310
311 if unlikely(bytes > 31 || !builder.has_capacity(Self::LEN_BITS + bits, 0)) {
312 return Err(Error::CellOverflow);
313 }
314
315 ok!(builder.store_small_uint(bytes, Self::LEN_BITS));
316
317 let (hi, lo) = self.into_words();
318 if let Some(high_bits) = bits.checked_sub(128) {
319 ok!(super::store_u128(builder, hi, high_bits));
320 bits -= high_bits;
321 }
322 super::store_u128(builder, lo, bits)
323 }
324}
325
326impl<'a> Load<'a> for VarUint248 {
327 fn load_from(slice: &mut CellSlice<'a>) -> Result<Self, Error> {
328 let mut bytes = ok!(slice.load_small_uint(Self::LEN_BITS));
329
330 let mut hi: u128 = 0;
331 if let Some(high_bytes) = bytes.checked_sub(16)
332 && high_bytes > 0
333 {
334 hi = ok!(super::load_u128(slice, high_bytes));
335 bytes -= high_bytes;
336 }
337
338 match super::load_u128(slice, bytes) {
339 Ok(lo) => Ok(Self::from_words(hi, lo)),
340 Err(e) => Err(e),
341 }
342 }
343}
344
345#[cfg(feature = "serde")]
346impl serde::Serialize for VarUint248 {
347 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
348 where
349 S: serde::Serializer,
350 {
351 if serializer.is_human_readable() {
352 serializer.collect_str(self)
353 } else {
354 self.0.serialize(serializer)
355 }
356 }
357}
358
359#[cfg(feature = "serde")]
360impl<'de> serde::Deserialize<'de> for VarUint248 {
361 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
362 where
363 D: serde::Deserializer<'de>,
364 {
365 use serde::de::{Error, Unexpected, Visitor};
366
367 struct VarUint248Visitor;
368
369 impl Visitor<'_> for VarUint248Visitor {
370 type Value = VarUint248;
371
372 fn expecting(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
373 f.write_str("a formatted 248-bit integer")
374 }
375
376 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
377 where
378 E: Error,
379 {
380 from_str_radix(v, 10, None).map_err(Error::custom)
381 }
382
383 fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
384 where
385 E: Error,
386 {
387 let Ok(string) = std::str::from_utf8(v) else {
388 return Err(Error::invalid_value(Unexpected::Bytes(v), &self));
389 };
390 self.visit_str(string)
391 }
392 }
393
394 if deserializer.is_human_readable() {
395 deserializer.deserialize_str(VarUint248Visitor)
396 } else {
397 <_>::deserialize(deserializer).map(Self)
398 }
399 }
400}
401
402#[cfg(feature = "arbitrary")]
403impl<'a> arbitrary::Arbitrary<'a> for VarUint248 {
404 #[inline]
405 fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
406 Ok(Self::from_words(
407 u.int_in_range(0..=(u128::MAX >> 8))?,
408 u.arbitrary()?,
409 ))
410 }
411
412 #[inline]
413 fn size_hint(_: usize) -> (usize, Option<usize>) {
414 (32, Some(32))
415 }
416}
417
418impl std::ops::Add<u128> for VarUint248 {
419 type Output = Self;
420
421 #[inline]
422 fn add(mut self, rhs: u128) -> Self::Output {
423 self += Self::new(rhs);
424 self
425 }
426}
427
428impl std::ops::Add for VarUint248 {
429 type Output = Self;
430
431 #[inline]
432 fn add(mut self, rhs: Self) -> Self::Output {
433 self += &rhs;
434 self
435 }
436}
437
438impl std::ops::Add<&Self> for VarUint248 {
439 type Output = Self;
440
441 #[inline]
442 fn add(mut self, rhs: &Self) -> Self::Output {
443 self += rhs;
444 self
445 }
446}
447
448impl std::ops::AddAssign<u128> for VarUint248 {
449 fn add_assign(&mut self, rhs: u128) {
450 std::ops::AddAssign::<&Self>::add_assign(self, &Self::new(rhs))
451 }
452}
453
454impl std::ops::AddAssign for VarUint248 {
455 fn add_assign(&mut self, rhs: Self) {
456 std::ops::AddAssign::<&Self>::add_assign(self, &rhs)
457 }
458}
459
460impl std::ops::AddAssign<&Self> for VarUint248 {
461 fn add_assign(&mut self, rhs: &Self) {
462 let (lo, carry) = self.low().overflowing_add(*rhs.low());
463 *self.low_mut() = lo;
464 *self.high_mut() = rhs
465 .high()
466 .wrapping_add(carry as _)
467 .wrapping_add(*rhs.high());
468 }
469}
470
471impl std::ops::Sub<u128> for VarUint248 {
472 type Output = Self;
473
474 #[inline]
475 fn sub(mut self, rhs: u128) -> Self::Output {
476 self -= &Self::new(rhs);
477 self
478 }
479}
480
481impl std::ops::Sub for VarUint248 {
482 type Output = Self;
483
484 #[inline]
485 fn sub(mut self, rhs: Self) -> Self::Output {
486 self -= &rhs;
487 self
488 }
489}
490
491impl std::ops::Sub<&Self> for VarUint248 {
492 type Output = Self;
493
494 #[inline]
495 fn sub(mut self, rhs: &Self) -> Self::Output {
496 self -= rhs;
497 self
498 }
499}
500
501impl std::ops::SubAssign<u128> for VarUint248 {
502 fn sub_assign(&mut self, rhs: u128) {
503 std::ops::SubAssign::<&Self>::sub_assign(self, &Self::new(rhs))
504 }
505}
506
507impl std::ops::SubAssign for VarUint248 {
508 #[inline]
509 fn sub_assign(&mut self, rhs: Self) {
510 std::ops::SubAssign::<&Self>::sub_assign(self, &rhs)
511 }
512}
513
514impl std::ops::SubAssign<&Self> for VarUint248 {
515 fn sub_assign(&mut self, rhs: &Self) {
516 let (lo, carry) = self.low().overflowing_sub(*rhs.low());
517 *self.low_mut() = lo;
518 *self.high_mut() = self
519 .high()
520 .wrapping_sub(carry as _)
521 .wrapping_sub(*rhs.high());
522 }
523}
524
525impl std::ops::Shr<i32> for VarUint248 {
526 type Output = Self;
527
528 #[inline]
529 fn shr(mut self, rhs: i32) -> Self::Output {
530 self >>= rhs as usize;
531 self
532 }
533}
534
535impl std::ops::Shr<u32> for VarUint248 {
536 type Output = Self;
537
538 #[inline]
539 fn shr(mut self, rhs: u32) -> Self::Output {
540 self >>= rhs as usize;
541 self
542 }
543}
544
545impl std::ops::Shr<usize> for VarUint248 {
546 type Output = Self;
547
548 #[inline]
549 fn shr(mut self, rhs: usize) -> Self::Output {
550 self >>= rhs;
551 self
552 }
553}
554
555impl std::ops::ShrAssign<usize> for VarUint248 {
556 fn shr_assign(&mut self, n: usize) {
557 debug_assert!(n < 256, "shr overflow");
558
559 match n {
560 0 => {}
561 1..=127 => {
562 let hi = *self.high();
563 *self.high_mut() >>= n;
564 *self.low_mut() >>= n;
565 *self.low_mut() |= hi << (128 - n);
566 }
567 _ => {
568 let hi = *self.high();
569 *self.high_mut() = 0;
570 *self.low_mut() = hi >> (n & 127);
571 }
572 }
573 }
574}
575
576impl std::ops::Shl<i32> for VarUint248 {
577 type Output = Self;
578
579 #[inline]
580 fn shl(mut self, rhs: i32) -> Self::Output {
581 self <<= rhs as usize;
582 self
583 }
584}
585
586impl std::ops::Shl<u32> for VarUint248 {
587 type Output = Self;
588
589 #[inline]
590 fn shl(mut self, rhs: u32) -> Self::Output {
591 self <<= rhs as usize;
592 self
593 }
594}
595
596impl std::ops::Shl<usize> for VarUint248 {
597 type Output = Self;
598
599 fn shl(mut self, rhs: usize) -> Self::Output {
600 self <<= rhs;
601 self
602 }
603}
604
605impl std::ops::ShlAssign<usize> for VarUint248 {
606 fn shl_assign(&mut self, n: usize) {
607 debug_assert!(n < 256, "shl overflow");
608
609 match n {
610 0 => {}
611 1..=127 => {
612 let lo = *self.low();
613 *self.low_mut() <<= n;
614 *self.high_mut() <<= n;
615 *self.high_mut() |= lo >> (128 - n);
616 }
617 _ => {
618 let lo = *self.low();
619 *self.low_mut() = 0;
620 *self.high_mut() = lo << (n & 127);
621 }
622 }
623 }
624}
625
626impl std::ops::Mul<u128> for VarUint248 {
627 type Output = Self;
628
629 #[inline]
630 fn mul(mut self, rhs: u128) -> Self::Output {
631 self *= rhs;
632 self
633 }
634}
635
636impl std::ops::Mul for VarUint248 {
637 type Output = Self;
638
639 #[inline]
640 fn mul(mut self, rhs: Self) -> Self::Output {
641 self *= rhs;
642 self
643 }
644}
645
646impl std::ops::Mul<&Self> for VarUint248 {
647 type Output = Self;
648
649 #[inline]
650 fn mul(mut self, rhs: &Self) -> Self::Output {
651 self *= rhs;
652 self
653 }
654}
655
656impl std::ops::MulAssign<u128> for VarUint248 {
657 #[inline]
658 fn mul_assign(&mut self, rhs: u128) {
659 std::ops::MulAssign::<&Self>::mul_assign(self, &Self::new(rhs))
660 }
661}
662
663impl std::ops::MulAssign for VarUint248 {
664 #[inline]
665 fn mul_assign(&mut self, rhs: Self) {
666 std::ops::MulAssign::<&Self>::mul_assign(self, &rhs)
667 }
668}
669
670impl std::ops::MulAssign<&Self> for VarUint248 {
671 fn mul_assign(&mut self, rhs: &Self) {
672 let mut r = umulddi3(self.low(), rhs.low());
675 let a_hi_mul_b_lo = self.high().wrapping_mul(*rhs.low());
676 let a_lo_mul_b_hi = self.low().wrapping_mul(*rhs.high());
677 *r.high_mut() = r
678 .high()
679 .wrapping_add(a_hi_mul_b_lo.wrapping_add(a_lo_mul_b_hi));
680
681 *self = r;
682 }
683}
684
685impl std::ops::Div<u128> for VarUint248 {
686 type Output = Self;
687
688 #[inline]
689 fn div(mut self, rhs: u128) -> Self::Output {
690 self /= VarUint248::new(rhs);
691 self
692 }
693}
694
695impl std::ops::Div for VarUint248 {
696 type Output = Self;
697
698 #[inline]
699 fn div(mut self, rhs: Self) -> Self::Output {
700 self /= rhs;
701 self
702 }
703}
704
705impl std::ops::Div<&Self> for VarUint248 {
706 type Output = Self;
707
708 #[inline]
709 fn div(mut self, rhs: &Self) -> Self::Output {
710 self /= rhs;
711 self
712 }
713}
714
715impl std::ops::DivAssign<u128> for VarUint248 {
716 #[inline]
717 fn div_assign(&mut self, rhs: u128) {
718 std::ops::DivAssign::<&Self>::div_assign(self, &VarUint248::new(rhs))
719 }
720}
721
722impl std::ops::DivAssign for VarUint248 {
723 #[inline]
724 fn div_assign(&mut self, rhs: Self) {
725 std::ops::DivAssign::<&Self>::div_assign(self, &rhs)
726 }
727}
728
729impl std::ops::DivAssign<&Self> for VarUint248 {
730 fn div_assign(&mut self, rhs: &Self) {
731 let (a, b) = (*self, rhs);
732
733 let res = unsafe { &mut *(self as *mut Self).cast() };
736 udivmod(res, &a, b, None);
737 }
738}
739
740impl std::ops::Rem<u128> for VarUint248 {
741 type Output = Self;
742
743 #[inline]
744 fn rem(mut self, rhs: u128) -> Self::Output {
745 self %= VarUint248::new(rhs);
746 self
747 }
748}
749
750impl std::ops::Rem for VarUint248 {
751 type Output = Self;
752
753 #[inline]
754 fn rem(mut self, rhs: Self) -> Self::Output {
755 self %= rhs;
756 self
757 }
758}
759
760impl std::ops::Rem<&Self> for VarUint248 {
761 type Output = Self;
762
763 #[inline]
764 fn rem(mut self, rhs: &Self) -> Self::Output {
765 self %= rhs;
766 self
767 }
768}
769
770impl std::ops::RemAssign<u128> for VarUint248 {
771 fn rem_assign(&mut self, rhs: u128) {
772 std::ops::RemAssign::<&Self>::rem_assign(self, &VarUint248::new(rhs))
773 }
774}
775
776impl std::ops::RemAssign for VarUint248 {
777 #[inline]
778 fn rem_assign(&mut self, rhs: Self) {
779 std::ops::RemAssign::<&Self>::rem_assign(self, &rhs)
780 }
781}
782
783impl std::ops::RemAssign<&Self> for VarUint248 {
784 fn rem_assign(&mut self, rhs: &Self) {
785 let mut res = MaybeUninit::uninit();
786 let (a, b) = (*self, rhs);
787
788 let r = unsafe { &mut *(self as *mut Self).cast() };
791 udivmod(&mut res, &a, b, Some(r));
792 }
793}
794
795#[inline]
796pub fn umulddi3(a: &u128, b: &u128) -> VarUint248 {
797 const BITS_IN_DWORD_2: u32 = 64;
798 const LOWER_MASK: u128 = u128::MAX >> BITS_IN_DWORD_2;
799
800 let mut low = (a & LOWER_MASK) * (b & LOWER_MASK);
801 let mut t = low >> BITS_IN_DWORD_2;
802 low &= LOWER_MASK;
803 t += (a >> BITS_IN_DWORD_2) * (b & LOWER_MASK);
804 low += (t & LOWER_MASK) << BITS_IN_DWORD_2;
805 let mut high = t >> BITS_IN_DWORD_2;
806 t = low >> BITS_IN_DWORD_2;
807 low &= LOWER_MASK;
808 t += (b >> BITS_IN_DWORD_2) * (a & LOWER_MASK);
809 low += (t & LOWER_MASK) << BITS_IN_DWORD_2;
810 high += t >> BITS_IN_DWORD_2;
811 high += (a >> BITS_IN_DWORD_2) * (b >> BITS_IN_DWORD_2);
812
813 VarUint248::from_words(high, low)
814}
815
816fn udivmod(
817 res: &mut MaybeUninit<VarUint248>,
818 a: &VarUint248,
819 b: &VarUint248,
820 rem: Option<&mut MaybeUninit<VarUint248>>,
821) {
822 if a.high() | b.high() == 0 {
825 if let Some(rem) = rem {
826 rem.write(VarUint248::from_words(0, a.low() % b.low()));
827 }
828 res.write(VarUint248::from_words(0, a.low() / b.low()));
829 return;
830 }
831
832 let dividend = *a;
833 let divisor = *b;
834 let quotient: VarUint248;
835 let mut remainder: VarUint248;
836
837 if divisor > dividend {
838 if let Some(rem) = rem {
839 rem.write(dividend);
840 }
841 res.write(VarUint248::ZERO);
842 return;
843 }
844 if *divisor.high() == 0 {
846 remainder = VarUint248::ZERO;
847 if dividend.high() < divisor.low() {
848 quotient = VarUint248::from_words(
850 0,
851 udiv256_by_128_to_128(
852 *dividend.high(),
853 *dividend.low(),
854 *divisor.low(),
855 remainder.low_mut(),
856 ),
857 );
858 } else {
859 quotient = VarUint248::from_words(
862 dividend.high() / divisor.low(),
863 udiv256_by_128_to_128(
864 dividend.high() % divisor.low(),
865 *dividend.low(),
866 *divisor.low(),
867 remainder.low_mut(),
868 ),
869 );
870 }
871 if let Some(rem) = rem {
872 rem.write(remainder);
873 }
874 res.write(quotient);
875 return;
876 }
877
878 (quotient, remainder) = div_mod_knuth(÷nd, &divisor);
879
880 if let Some(rem) = rem {
881 rem.write(remainder);
882 }
883 res.write(quotient);
884}
885
886#[inline(always)]
887fn udiv256_by_128_to_128(u1: u128, u0: u128, mut v: u128, r: &mut u128) -> u128 {
888 const N_UDWORD_BITS: u32 = 128;
891 const B: u128 = 1 << (N_UDWORD_BITS / 2); let (un1, un0): (u128, u128); let (vn1, vn0): (u128, u128); let (mut q1, mut q0): (u128, u128); let (un128, un21, un10): (u128, u128, u128); let s = v.leading_zeros();
898 if s > 0 {
899 v <<= s;
901 un128 = (u1 << s) | (u0 >> (N_UDWORD_BITS - s));
902 un10 = u0 << s; } else {
904 un128 = u1;
906 un10 = u0;
907 }
908
909 vn1 = v >> (N_UDWORD_BITS / 2);
911 vn0 = v & 0xFFFF_FFFF_FFFF_FFFF;
912
913 un1 = un10 >> (N_UDWORD_BITS / 2);
915 un0 = un10 & 0xFFFF_FFFF_FFFF_FFFF;
916
917 q1 = un128 / vn1;
919 let mut rhat = un128 - q1 * vn1;
920
921 while q1 >= B || q1 * vn0 > B * rhat + un1 {
923 q1 -= 1;
924 rhat += vn1;
925 if rhat >= B {
926 break;
927 }
928 }
929
930 un21 = un128
931 .wrapping_mul(B)
932 .wrapping_add(un1)
933 .wrapping_sub(q1.wrapping_mul(v));
934
935 q0 = un21 / vn1;
937 rhat = un21 - q0 * vn1;
938
939 while q0 >= B || q0 * vn0 > B * rhat + un0 {
941 q0 -= 1;
942 rhat += vn1;
943 if rhat >= B {
944 break;
945 }
946 }
947
948 *r = (un21
949 .wrapping_mul(B)
950 .wrapping_add(un0)
951 .wrapping_sub(q0.wrapping_mul(v)))
952 >> s;
953 q1 * B + q0
954}
955
956#[inline]
957pub fn div_mod_knuth(u: &VarUint248, v: &VarUint248) -> (VarUint248, VarUint248) {
958 const N_UDWORD_BITS: u32 = 128;
961
962 #[inline]
963 fn full_shl(a: &VarUint248, shift: u32) -> [u128; 3] {
964 debug_assert!(shift < N_UDWORD_BITS);
965 let mut u = [0_u128; 3];
966 let u_lo = a.low() << shift;
967 let u_hi = *a >> (N_UDWORD_BITS - shift);
968 u[0] = u_lo;
969 u[1] = *u_hi.low();
970 u[2] = *u_hi.high();
971
972 u
973 }
974
975 #[inline]
976 fn full_shr(u: &[u128; 3], shift: u32) -> VarUint248 {
977 debug_assert!(shift < N_UDWORD_BITS);
978 let mut res = VarUint248::ZERO;
979 *res.low_mut() = u[0] >> shift;
980 *res.high_mut() = u[1] >> shift;
981 if shift > 0 {
983 let sh = N_UDWORD_BITS - shift;
984 *res.low_mut() |= u[1] << sh;
985 *res.high_mut() |= u[2] << sh;
986 }
987
988 res
989 }
990
991 #[inline]
993 const fn split_u128_to_u128(a: u128) -> (u128, u128) {
994 (a & 0xFFFFFFFFFFFFFFFF, a >> (N_UDWORD_BITS / 2))
995 }
996
997 #[inline]
999 const fn fullmul_u128(a: u128, b: u128) -> (u128, u128) {
1000 let (a0, a1) = split_u128_to_u128(a);
1001 let (b0, b1) = split_u128_to_u128(b);
1002
1003 let mut t = a0 * b0;
1004 let mut k: u128;
1005 let w3: u128;
1006 (w3, k) = split_u128_to_u128(t);
1007
1008 t = a1 * b0 + k;
1009 let (w1, w2) = split_u128_to_u128(t);
1010 t = a0 * b1 + w1;
1011 k = t >> 64;
1012
1013 let w_hi = a1 * b1 + w2 + k;
1014 let w_lo = (t << 64) + w3;
1015
1016 (w_lo, w_hi)
1017 }
1018
1019 #[inline]
1020 fn fullmul_u256_u128(a: &VarUint248, b: u128) -> [u128; 3] {
1021 let mut acc = [0_u128; 3];
1022 let mut lo: u128;
1023 let mut carry: u128;
1024 let c: bool;
1025 if b != 0 {
1026 (lo, carry) = fullmul_u128(*a.low(), b);
1027 acc[0] = lo;
1028 acc[1] = carry;
1029 (lo, carry) = fullmul_u128(*a.high(), b);
1030 (acc[1], c) = acc[1].overflowing_add(lo);
1031 acc[2] = carry + c as u128;
1032 }
1033
1034 acc
1035 }
1036
1037 #[inline]
1038 const fn add_carry(a: u128, b: u128, c: bool) -> (u128, bool) {
1039 let (res1, overflow1) = b.overflowing_add(c as u128);
1040 let (res2, overflow2) = u128::overflowing_add(a, res1);
1041
1042 (res2, overflow1 || overflow2)
1043 }
1044
1045 #[inline]
1046 const fn sub_carry(a: u128, b: u128, c: bool) -> (u128, bool) {
1047 let (res1, overflow1) = b.overflowing_add(c as u128);
1048 let (res2, overflow2) = u128::overflowing_sub(a, res1);
1049
1050 (res2, overflow1 || overflow2)
1051 }
1052
1053 let shift = v.high().leading_zeros();
1058 debug_assert!(shift < N_UDWORD_BITS);
1059 let v = *v << shift;
1060 debug_assert!(v.high() >> (N_UDWORD_BITS - 1) == 1);
1061 let mut u = full_shl(u, shift);
1063
1064 let mut q = VarUint248::ZERO;
1066 let v_n_1 = *v.high();
1067 let v_n_2 = *v.low();
1068
1069 let mut r_hat: u128 = 0;
1071 let u_jn = u[2];
1072
1073 let mut q_hat = if u_jn < v_n_1 {
1079 let mut q_hat = udiv256_by_128_to_128(u_jn, u[1], v_n_1, &mut r_hat);
1081 let mut overflow: bool;
1082 loop {
1084 let another_iteration = {
1085 let (lo, hi) = fullmul_u128(q_hat, v_n_2);
1087 hi > r_hat || (hi == r_hat && lo > u[0])
1088 };
1089 if !another_iteration {
1090 break;
1091 }
1092 q_hat -= 1;
1093 (r_hat, overflow) = r_hat.overflowing_add(v_n_1);
1094 if overflow {
1096 break;
1097 }
1098 }
1099 q_hat
1100 } else {
1101 u128::MAX
1103 };
1104
1105 let q_hat_v = fullmul_u256_u128(&v, q_hat);
1113 let mut c = false;
1115 (u[0], c) = sub_carry(u[0], q_hat_v[0], c);
1116 (u[1], c) = sub_carry(u[1], q_hat_v[1], c);
1117 (u[2], c) = sub_carry(u[2], q_hat_v[2], c);
1118
1119 if c {
1123 q_hat -= 1;
1124 c = false;
1126 (u[0], c) = add_carry(u[0], *v.low(), c);
1127 (u[1], c) = add_carry(u[1], *v.high(), c);
1128 u[2] = u[2].wrapping_add(c as u128);
1129 }
1130
1131 *q.low_mut() = q_hat;
1133
1134 let remainder = full_shr(&u, shift);
1136
1137 (q, remainder)
1138}
1139
1140impl std::fmt::Display for VarUint248 {
1141 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1142 fmt_var_uint248(*self, f)
1143 }
1144}
1145
1146const DEC_DIGITS_LUT: &[u8; 200] = b"\
1147 0001020304050607080910111213141516171819\
1148 2021222324252627282930313233343536373839\
1149 4041424344454647484950515253545556575859\
1150 6061626364656667686970717273747576777879\
1151 8081828384858687888990919293949596979899";
1152
1153fn fmt_var_uint248(mut n: VarUint248, f: &mut std::fmt::Formatter) -> std::fmt::Result {
1154 let mut buf = [MaybeUninit::<u8>::uninit(); 79];
1158 let mut curr = buf.len() as isize;
1159 let buf_ptr = &mut buf[0] as *mut _ as *mut u8;
1160 let lut_ptr = DEC_DIGITS_LUT.as_ptr();
1161
1162 unsafe {
1170 while n >= 10000 {
1172 let rem = (n % 10000).as_isize();
1173 n /= 10000;
1174
1175 let d1 = (rem / 100) << 1;
1176 let d2 = (rem % 100) << 1;
1177 curr -= 4;
1178
1179 std::ptr::copy_nonoverlapping(lut_ptr.offset(d1), buf_ptr.offset(curr), 2);
1183 std::ptr::copy_nonoverlapping(lut_ptr.offset(d2), buf_ptr.offset(curr + 2), 2);
1184 }
1185
1186 let mut n = n.as_isize(); if n >= 100 {
1191 let d1 = (n % 100) << 1;
1192 n /= 100;
1193 curr -= 2;
1194 std::ptr::copy_nonoverlapping(lut_ptr.offset(d1), buf_ptr.offset(curr), 2);
1195 }
1196
1197 if n < 10 {
1199 curr -= 1;
1200 *buf_ptr.offset(curr) = (n as u8) + b'0';
1201 } else {
1202 let d1 = n << 1;
1203 curr -= 2;
1204 std::ptr::copy_nonoverlapping(lut_ptr.offset(d1), buf_ptr.offset(curr), 2);
1205 }
1206 }
1207
1208 let buf_slice = unsafe {
1211 std::str::from_utf8_unchecked(std::slice::from_raw_parts(
1212 buf_ptr.offset(curr),
1213 buf.len() - curr as usize,
1214 ))
1215 };
1216 f.pad_integral(true, "", buf_slice)
1217}
1218
1219impl FromStr for VarUint248 {
1220 type Err = std::num::ParseIntError;
1221
1222 fn from_str(s: &str) -> Result<Self, Self::Err> {
1223 from_str_radix(s, 10, None)
1224 }
1225}
1226
1227fn from_str_radix(
1228 src: &str,
1229 radix: u32,
1230 prefix: Option<&str>,
1231) -> Result<VarUint248, std::num::ParseIntError> {
1232 use std::num::IntErrorKind::*;
1233
1234 const fn pie(kind: std::num::IntErrorKind) -> std::num::ParseIntError {
1237 unsafe { std::mem::transmute(kind) }
1238 }
1239
1240 assert!(
1241 (2..=36).contains(&radix),
1242 "from_str_radix_int: must lie in the range `[2, 36]` - found {radix}",
1243 );
1244
1245 if src.is_empty() {
1246 return Err(pie(Empty));
1247 }
1248
1249 let src = src.as_bytes();
1254
1255 let prefixed_digits = match src[0] {
1256 b'+' | b'-' if src[1..].is_empty() => {
1257 return Err(pie(InvalidDigit));
1258 }
1259 b'+' => &src[1..],
1260 _ => src,
1261 };
1262
1263 let digits = match prefix {
1264 Some(prefix) => prefixed_digits
1265 .strip_prefix(prefix.as_bytes())
1266 .ok_or(pie(InvalidDigit))?,
1267 None => prefixed_digits,
1268 };
1269 if digits.is_empty() {
1270 return Err(pie(InvalidDigit));
1271 }
1272
1273 let mut result = VarUint248::ZERO;
1274
1275 if radix <= 16 && digits.len() <= 64 {
1276 for &c in digits {
1277 result *= radix as u128;
1278 let Some(x) = (c as char).to_digit(radix) else {
1279 return Err(pie(InvalidDigit));
1280 };
1281 result += x as u128;
1282 }
1283 } else {
1284 for &c in digits {
1285 match result.checked_mul(&VarUint248::from(radix)) {
1286 Some(mul) => result = mul,
1287 None => return Err(pie(PosOverflow)),
1288 }
1289
1290 let Some(x) = (c as char).to_digit(radix) else {
1291 return Err(pie(InvalidDigit));
1292 };
1293
1294 match result.checked_add(&VarUint248::from(x)) {
1295 Some(add) => result = add,
1296 None => return Err(pie(PosOverflow)),
1297 }
1298 }
1299 }
1300
1301 Ok(result)
1302}
1303
1304#[cfg(test)]
1305mod tests {
1306 use super::*;
1307
1308 #[test]
1309 fn valid_range_is_correct() {
1310 assert!(VarUint248::ZERO.is_valid());
1311 assert!(VarUint248::ONE.is_valid());
1312 assert!(VarUint248::new(123123).is_valid());
1313 assert!(VarUint248::new(u128::MAX).is_valid());
1314 assert!(VarUint248::from_words(u128::MAX >> 8, u128::MAX).is_valid());
1316
1317 assert!(!VarUint248::from_words(u128::MAX >> 7, u128::MAX).is_valid());
1318 assert!(!VarUint248::from_words(u128::MAX, u128::MAX).is_valid());
1319
1320 assert_eq!(
1321 VarUint248::new(123).saturating_sub(&VarUint248::new(321)),
1322 VarUint248::ZERO
1323 );
1324
1325 assert_eq!(
1326 VarUint248::from_words(u128::MAX, u128::MAX).saturating_sub(&VarUint248::new(1)),
1327 VarUint248::MAX
1328 );
1329 assert_eq!(
1330 VarUint248::from_words(u128::MAX, u128::MAX)
1331 .saturating_sub(&VarUint248::from_words(u128::MAX, u128::MAX)),
1332 VarUint248::ZERO
1333 );
1334 }
1335
1336 #[test]
1337 fn store_into_cell() {
1338 for i in 0..128 {
1339 let lo = 1u128 << i;
1340
1341 let value = VarUint248::new(lo);
1342 let cell = CellBuilder::build_from(value).unwrap();
1343 assert_eq!(value.bit_len().unwrap(), cell.bit_len());
1344 }
1345 }
1346
1347 #[test]
1348 fn load_from_cell() {
1349 let mut lo: u128 = 0xababcdef89abcdefdeadbeeffafacafe;
1350 for _ in 0..=128 {
1351 let value = VarUint248::new(lo);
1352
1353 let cell = CellBuilder::build_from(value).unwrap();
1354
1355 let parsed_value = cell.parse::<VarUint248>().unwrap();
1356 assert_eq!(parsed_value, value);
1357
1358 lo >>= 1;
1359 }
1360 }
1361
1362 #[test]
1363 fn identity() {
1364 assert_eq!(VarUint248::ZERO + VarUint248::ZERO, VarUint248::ZERO);
1365 assert_eq!(VarUint248::ONE * VarUint248::ZERO, VarUint248::ZERO);
1366 assert_eq!(VarUint248::ONE * VarUint248::ONE, VarUint248::ONE);
1367 }
1368
1369 #[test]
1370 fn cmp() {
1371 let x = VarUint248::from_words(0, 100000000000000000000000000000000000000);
1373 let y = VarUint248::from_words(2938735877, 18960114910927365649471927446130393088);
1375 assert!(x < y);
1376 assert_eq!(x.cmp(&y), std::cmp::Ordering::Less);
1377 assert!(y > x);
1378 assert_eq!(y.cmp(&x), std::cmp::Ordering::Greater);
1379
1380 let x = VarUint248::new(100);
1381 let y = VarUint248::new(100);
1382 assert!(x <= y);
1383 assert_eq!(x.cmp(&y), std::cmp::Ordering::Equal);
1384 }
1385
1386 #[test]
1387 fn mul() {
1388 assert_eq!(VarUint248::new(6) * 7, VarUint248::new(42));
1389 assert_eq!(
1390 VarUint248::new(6).checked_mul(&VarUint248::new(7)),
1391 Some(VarUint248::new(42))
1392 );
1393
1394 assert_eq!(
1395 VarUint248::MAX.checked_mul(&VarUint248::ONE),
1396 Some(VarUint248::MAX)
1397 );
1398 assert_eq!(
1399 VarUint248::MAX.checked_mul(&VarUint248::ZERO),
1400 Some(VarUint248::ZERO)
1401 );
1402
1403 assert_eq!(
1404 VarUint248::new(u128::MAX) * u128::MAX,
1405 VarUint248::from_words(!0 << 1, 1),
1406 );
1407 assert_eq!(
1408 VarUint248::new(u128::MAX).checked_mul(&VarUint248::new(u128::MAX)),
1409 Some(VarUint248::from_words(!0 << 1, 1))
1410 );
1411
1412 assert_eq!(VarUint248::MAX.checked_mul(&VarUint248::new(257)), None);
1413 assert_eq!(VarUint248::MAX.checked_mul(&VarUint248::MAX), None);
1414 }
1415
1416 #[test]
1417 fn division() {
1418 assert_eq!(VarUint248::new(100) / 9, 11);
1422
1423 assert_eq!(VarUint248::new(!0u128) / (VarUint248::ONE << 128), 0u128);
1427
1428 assert_eq!(
1432 VarUint248::from_words(100, 0) / VarUint248::from_words(10, 0),
1433 10
1434 );
1435
1436 assert_eq!(
1440 VarUint248::from_words(100, 1337) / (VarUint248::ONE << 130u32),
1441 25
1442 );
1443 assert_eq!(
1444 VarUint248::from_words(1337, !0) / VarUint248::from_words(63, 0),
1445 21
1446 );
1447
1448 assert_eq!(
1452 VarUint248::from_words(42, 0) / VarUint248::ONE,
1453 VarUint248::from_words(42, 0),
1454 );
1455 assert_eq!(
1456 VarUint248::from_words(42, 42) / (VarUint248::ONE << 42),
1457 42u128 << (128 - 42),
1458 );
1459 assert_eq!(
1460 VarUint248::from_words(1337, !0) / 0xc0ffee,
1461 35996389033280467545299711090127855,
1462 );
1463 assert_eq!(
1464 VarUint248::from_words(42, 0) / 99,
1465 144362216269489045105674075880144089708,
1466 );
1467
1468 assert_eq!(
1472 VarUint248::from_words(100, 100) / VarUint248::from_words(1000, 1000),
1473 0,
1474 );
1475 assert_eq!(
1476 VarUint248::from_words(1337, !0) / VarUint248::from_words(43, !0),
1477 30,
1478 );
1479 }
1480
1481 #[test]
1482 #[should_panic]
1483 fn division_by_zero() {
1484 _ = VarUint248::ONE / 0;
1485 }
1486
1487 #[test]
1488 fn remainder() {
1489 assert_eq!(VarUint248::new(100) % 9, 1);
1493
1494 assert_eq!(
1498 VarUint248::new(!0u128) % (VarUint248::ONE << 128u32),
1499 !0u128
1500 );
1501
1502 assert_eq!(
1506 VarUint248::from_words(100, 0) % VarUint248::from_words(10, 0),
1507 0
1508 );
1509
1510 assert_eq!(
1514 VarUint248::from_words(100, 1337) % (VarUint248::ONE << 130u32),
1515 1337
1516 );
1517 assert_eq!(
1518 VarUint248::from_words(1337, !0) % VarUint248::from_words(63, 0),
1519 VarUint248::from_words(14, !0),
1520 );
1521
1522 assert_eq!(VarUint248::from_words(42, 0) % VarUint248::ONE, 0);
1526 assert_eq!(
1527 VarUint248::from_words(42, 42) % (VarUint248::ONE << 42),
1528 42u128
1529 );
1530 assert_eq!(VarUint248::from_words(1337, !0) % 0xc0ffee, 1910477);
1531 assert_eq!(VarUint248::from_words(42, 0) % 99, 60);
1532
1533 assert_eq!(
1537 VarUint248::from_words(100, 100) % VarUint248::from_words(1000, 1000),
1538 VarUint248::from_words(100, 100),
1539 );
1540 assert_eq!(
1541 VarUint248::from_words(1337, !0) % VarUint248::from_words(43, !0),
1542 VarUint248::from_words(18, 29),
1543 );
1544 }
1545
1546 #[test]
1547 #[should_panic]
1548 fn remainder_by_zero() {
1549 _ = VarUint248::ONE % 0;
1550 }
1551}