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