1use std::cmp::Ordering;
4use std::fmt::Write;
5use std::mem::ManuallyDrop;
6use std::ops::{Add, Shl, Shr};
7use std::ptr::NonNull;
8use std::{fmt, mem};
9
10use crate::util::IsFloatingPoint;
11
12#[derive(Eq)]
41pub struct Natural {
42 ptr: std::ptr::NonNull<u64>,
57 len: u64,
62 shl: u64,
65}
66
67const DANGLING: NonNull<u64> = {
69 assert!(
70 std::mem::align_of::<u64>() > 1,
71 "The implementation of `Natural` assumes that `u64` has at least 2 byte alignment"
72 );
73 NonNull::without_provenance(std::num::NonZeroUsize::new(1).unwrap())
74};
75
76#[inline]
77fn shl_amount(value: u64) -> u32 {
78 if value == 0 {
79 0
80 } else {
81 value.trailing_zeros()
82 }
83}
84
85#[inline]
86fn bit_width(digits: &[u64], shl: u64) -> u128 {
87 (u64::BITS as u128 * digits.len() as u128) - digits.last().unwrap().leading_zeros() as u128
88 + shl as u128
89}
90
91impl Natural {
92 pub const ZERO: Self = Self {
94 ptr: DANGLING,
95 len: 0,
96 shl: 0,
97 };
98 const NAN: Self = Self {
100 ptr: DANGLING,
101 len: 0,
102 shl: u64::MAX,
103 };
104
105 #[allow(unused)] fn check_inv(&self) {
107 if self.ptr == DANGLING {
108 if self.len == 0 {
109 assert!(self.shl == 0 || self.shl == u64::MAX);
110 } else {
111 assert_eq!(self.len & 1, 1);
112 }
113 } else {
114 assert_ne!(self.len, 0);
115 assert_ne!(self.len, 1);
116 let digits =
118 unsafe { std::slice::from_raw_parts(self.ptr.as_ptr(), self.len as usize) };
119 if *digits.last().unwrap() == 0 {
120 assert_eq!(digits[digits.len() - 2] >> (u64::BITS - 1), 1);
121 }
122 assert_eq!(digits[0] & 1, 1);
123 }
124 }
125
126 #[inline]
142 #[doc(hidden)]
143 pub fn into_raw_parts(self) -> (*mut u64, u64, u64) {
144 let ptr = if self.ptr == DANGLING {
145 std::ptr::null_mut()
146 } else {
147 self.ptr.as_ptr()
148 };
149 let this = ManuallyDrop::new(self);
150 (ptr, this.len, this.shl)
151 }
152
153 #[inline]
172 #[doc(hidden)]
173 pub unsafe fn from_raw_parts(ptr: *mut u64, len: u64, exp: u64) -> Self {
174 debug_assert!(ptr.is_null() || len != 0);
175 debug_assert!(len != 0 || exp == 0 || exp == u64::MAX);
176 let ptr = NonNull::new(ptr).unwrap_or(DANGLING);
177 let num = Self { ptr, len, shl: exp };
178 #[cfg(debug_assertions)]
179 num.check_inv();
180 num
181 }
182
183 #[inline]
184 fn from_mantissa_single_with_shl(mantissa: u64, shl: u64) -> Self {
185 debug_assert!(
186 mantissa & 1 == 1 || (mantissa == 0 && (shl == 0 || shl == u64::MAX)),
187 "invalid arguments (mantissa: {mantissa}, shl: {shl})"
188 );
189 Self {
190 ptr: DANGLING,
191 len: mantissa,
192 shl,
193 }
194 }
195
196 #[inline]
197 fn from_mantissa_with_shl(mantissa: Box<[u64]>, shl: u64) -> Self {
198 let len = mantissa.len() as u64;
199 debug_assert!(len >= 2);
200 debug_assert!(
201 mantissa[len as usize - 1] != 0 || mantissa[len as usize - 2] >> (u64::BITS - 1) == 1
202 );
203 debug_assert_eq!(mantissa[0] & 1, 1);
204 let ptr = NonNull::new(Box::into_raw(mantissa).cast()).unwrap();
205 Self { ptr, len, shl }
206 }
207
208 pub fn from_le_digits(digits: &[u64]) -> Self {
213 let mut digits = digits;
214 while let [r @ .., 0] = digits {
215 digits = r;
216 }
217 let mut shl_digits = 0u64;
218 while let [0, r @ ..] = digits {
219 digits = r;
220 shl_digits += 1;
221 }
222 match digits {
223 [] => Self::ZERO,
224 &[d] => {
225 debug_assert_ne!(d, 0);
226 let shl = d.trailing_zeros();
227 Self {
228 ptr: DANGLING,
229 len: d >> shl,
230 shl: (shl as u64).saturating_add(shl_digits.saturating_mul(u64::BITS as u64)),
231 }
232 }
233 &[lsd, .., msd] => {
234 debug_assert_ne!(lsd, 0);
235 let shr_bits = lsd.trailing_zeros();
236 let shl = shl_digits.saturating_mul(u64::BITS as u64);
237 if shr_bits == 0 {
238 return Self {
239 ptr: NonNull::new(Box::<[u64]>::into_raw(digits.into()).cast()).unwrap(),
240 len: digits.len() as u64,
241 shl,
242 };
243 }
244 let shl = shl.saturating_add(shr_bits as u64);
245
246 let len = digits.len() - ((shr_bits + msd.leading_zeros()) / u64::BITS) as usize;
247 if len == 1 {
248 return Self {
249 ptr: DANGLING,
250 len: msd.rotate_right(shr_bits) | (lsd >> shr_bits),
251 shl,
252 };
253 }
254
255 let lower_mask = u64::MAX >> shr_bits;
256 let upper_mask = !lower_mask;
257 let mut v = Vec::with_capacity(len);
258 let mut lower = lsd >> shr_bits;
259 v.extend(digits[1..].iter().map(|&d| {
260 let rot = d.rotate_right(shr_bits);
261 let d = lower | (rot & upper_mask);
262 lower = rot & lower_mask;
263 d
264 }));
265 if v.len() != len {
266 v.push(lower);
267 }
268 debug_assert_eq!(v.len(), len);
269
270 Self {
271 ptr: NonNull::new(Box::into_raw(v.into_boxed_slice()).cast()).unwrap(),
272 len: len as u64,
273 shl,
274 }
275 }
276 }
277 }
278
279 #[inline]
285 pub fn mantissa(&self) -> &[u64] {
286 let digits = if self.ptr == DANGLING {
287 std::slice::from_ref(&self.len)
288 } else {
289 let digits =
291 unsafe { std::slice::from_raw_parts(self.ptr.as_ptr(), self.len as usize) };
292 if *unsafe { digits.last().unwrap_unchecked() } == 0 {
294 &digits[..self.len as usize - 1]
295 } else {
296 digits
297 }
298 };
299 unsafe { std::hint::assert_unchecked(!digits.is_empty()) };
301 digits
302 }
303
304 #[inline]
309 fn mantissa_raw(&self) -> &[u64] {
310 let digits = if self.ptr == DANGLING {
311 std::slice::from_ref(&self.len)
312 } else {
313 unsafe { std::slice::from_raw_parts(self.ptr.as_ptr(), self.len as usize) }
315 };
316 unsafe { std::hint::assert_unchecked(!digits.is_empty()) };
318 digits
319 }
320
321 #[inline]
326 fn mantissa_mut(&mut self) -> &mut [u64] {
327 let digits = if self.ptr == DANGLING {
328 std::slice::from_mut(&mut self.len)
329 } else {
330 unsafe { std::slice::from_raw_parts_mut(self.ptr.as_ptr(), self.len as usize) }
332 };
333 unsafe { std::hint::assert_unchecked(!digits.is_empty()) };
335 digits
336 }
337
338 #[inline(always)]
340 pub fn exp(&self) -> u64 {
341 self.shl
342 }
343
344 #[inline(always)]
346 pub fn is_nan(&self) -> bool {
347 self.shl == u64::MAX
348 }
349
350 pub fn bit_width(&self) -> u128 {
353 bit_width(self.mantissa_raw(), self.shl)
354 }
355}
356
357impl Drop for Natural {
358 fn drop(&mut self) {
359 if self.ptr != DANGLING {
360 let slice = std::ptr::slice_from_raw_parts_mut(self.ptr.as_ptr(), self.len as usize);
361 drop(unsafe { Box::from_raw(slice) });
363 }
364 }
365}
366
367unsafe impl Send for Natural {}
369unsafe impl Sync for Natural {}
370
371impl Clone for Natural {
372 fn clone(&self) -> Self {
373 if self.ptr == DANGLING {
374 return Self { ..*self };
375 }
376 let slice = std::ptr::slice_from_raw_parts(self.ptr.as_ptr(), self.len as usize);
377 let clone: *mut [u64] = Box::into_raw(unsafe { &*slice }.into());
380 Self {
381 ptr: NonNull::new(clone.cast()).unwrap(),
382 ..*self
383 }
384 }
385
386 fn clone_from(&mut self, source: &Self) {
387 self.shl = source.shl;
388 if self.ptr == DANGLING {
389 if source.ptr != DANGLING {
390 let slice = std::ptr::slice_from_raw_parts(source.ptr.as_ptr(), self.len as usize);
391 let clone: *mut [u64] = Box::into_raw(unsafe { &*slice }.into());
394 self.ptr = NonNull::new(clone.cast()).unwrap();
395 }
396 self.len = source.len;
397 return;
398 }
399
400 let dst = std::ptr::slice_from_raw_parts_mut(self.ptr.as_ptr(), self.len as usize);
401 if source.ptr != DANGLING {
402 let src =
405 unsafe { std::slice::from_raw_parts(source.ptr.as_ptr(), source.len as usize) };
406 if self.len == source.len {
407 unsafe { &mut *dst }.copy_from_slice(src);
410 return;
411 }
412 self.ptr = NonNull::new(Box::<[u64]>::into_raw(src.into()).cast()).unwrap();
413 }
414 self.len = source.len;
415
416 drop(unsafe { Box::from_raw(dst) });
419 }
420}
421
422impl PartialEq for Natural {
423 fn eq(&self, other: &Self) -> bool {
424 if self.shl != other.shl {
425 return false;
426 }
427 if self.is_nan() {
428 return true; }
430 self.mantissa() == other.mantissa()
431 }
432}
433impl PartialOrd for Natural {
434 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
435 if self.is_nan() || other.is_nan() {
436 return None;
437 }
438
439 let l_digits = self.mantissa();
440 let r_digits = other.mantissa();
441
442 let l_bw = bit_width(l_digits, self.shl);
443 let r_bw = bit_width(r_digits, other.shl);
444 if l_bw != r_bw {
445 return Some(l_bw.cmp(&r_bw));
446 }
447
448 let (&l_msd, mut l_digits) = l_digits.split_last().unwrap();
449 let (&r_msd, mut r_digits) = r_digits.split_last().unwrap();
450 let l_shl = l_msd.leading_zeros();
451 let r_shl = r_msd.leading_zeros();
452 let mut l = l_msd << l_shl;
453 let mut r = r_msd << r_shl;
454
455 let l_upper_mask = u64::MAX << l_shl;
456 let l_lower_mask = !l_upper_mask;
457 let r_upper_mask = u64::MAX << r_shl;
458 let r_lower_mask = !r_upper_mask;
459 while let ([l_rest @ .., l_next], [r_rest @ .., r_next]) = (l_digits, r_digits) {
460 let l_rot = l_next.rotate_left(l_shl);
461 let r_rot = r_next.rotate_left(r_shl);
462 let l_digit = l | (l_rot & l_lower_mask);
463 let r_digit = r | (r_rot & r_lower_mask);
464
465 if l_digit != r_digit {
466 return Some(l_digit.cmp(&r_digit));
467 }
468
469 l = l_rot & l_upper_mask;
470 r = r_rot & r_upper_mask;
471 l_digits = l_rest;
472 r_digits = r_rest;
473 }
474
475 Some(match (l_digits, r_digits) {
476 ([], []) => l.cmp(&r),
477 ([.., l_next], _) => {
478 debug_assert!(r_digits.is_empty());
479 let cmp = (l | (l_next.rotate_left(l_shl) & l_lower_mask)).cmp(&r);
480 cmp.then(Ordering::Greater)
484 }
485 (_, [.., r_next]) => {
486 let cmp = l.cmp(&(r | (r_next.rotate_left(r_shl) & r_lower_mask)));
487 cmp.then(Ordering::Less)
488 }
489 })
490 }
491}
492
493impl std::hash::Hash for Natural {
494 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
495 if self.is_nan() {
496 1.hash(state);
497 } else {
498 debug_assert!(
499 self.len != 0 || self.shl == 0,
500 "0 has a unique representation"
501 );
502 self.shl.hash(state);
503 self.mantissa().hash(state);
504 }
505 }
506}
507
508impl IsFloatingPoint for Natural {
510 const FLOATING_POINT: bool = false;
511 const MIN_EXP: i32 = 0;
512}
513
514impl From<u128> for Natural {
515 #[inline]
516 fn from(value: u128) -> Self {
517 if value == 0 {
518 return Self::ZERO;
519 }
520 let leading = value.leading_zeros();
521 let shl = value.trailing_zeros();
522 if leading - shl <= u64::BITS {
523 Self::from_mantissa_single_with_shl((value >> shl) as u64, shl as u64)
524 } else {
525 let value = value >> shl;
526 Self::from_mantissa_with_shl(
527 [value as u64, (value >> u64::BITS) as u64].into(),
528 shl as u64,
529 )
530 }
531 }
532}
533impl From<u64> for Natural {
534 #[inline]
535 fn from(value: u64) -> Self {
536 let shl = shl_amount(value);
537 Self::from_mantissa_single_with_shl(value >> shl, shl as u64)
538 }
539}
540impl From<u32> for Natural {
541 #[inline(always)]
542 fn from(value: u32) -> Self {
543 Self::from(value as u64)
544 }
545}
546impl From<u16> for Natural {
547 #[inline(always)]
548 fn from(value: u16) -> Self {
549 Self::from(value as u64)
550 }
551}
552impl From<u8> for Natural {
553 #[inline(always)]
554 fn from(value: u8) -> Self {
555 Self::from(value as u64)
556 }
557}
558
559impl Add for Natural {
560 type Output = Self;
561 fn add(mut self, mut rhs: Self) -> Self {
562 if rhs.len == 0 {
563 return self;
564 }
565 if self.len == 0 {
566 return rhs;
567 }
568
569 if self.shl > rhs.shl {
570 mem::swap(&mut self, &mut rhs);
571 }
572
573 let l_shl = self.shl;
574 let r_shl = rhs.shl;
575 let l_digits = self.mantissa_mut();
576 let r_digits = rhs.mantissa_mut();
577
578 let l_bit_width = bit_width(l_digits, l_shl);
579 let r_bit_width = bit_width(r_digits, r_shl);
580 let bit_width = std::cmp::max(l_bit_width, r_bit_width) + 1;
582
583 if l_shl < r_shl {
584 if r_shl == u64::MAX {
585 return Self::NAN;
586 }
587
588 let bit_len = bit_width - l_shl as u128;
590 let len = bit_len.div_ceil(u64::BITS as u128) as usize;
591 debug_assert_ne!(len, 0);
592
593 let start_digit = ((r_shl - l_shl) / u64::BITS as u64) as usize;
594 let start_bit = (r_shl - l_shl) as u32 % u64::BITS;
595 let upper_mask = u64::MAX << start_bit;
596 let lower_mask = !upper_mask;
597
598 if bit_len <= (u64::BITS + 1) as u128 {
599 debug_assert_eq!(start_digit, 0);
600 debug_assert_eq!(self.ptr, DANGLING);
601 debug_assert_eq!(rhs.ptr, DANGLING);
602 debug_assert_eq!(rhs.len.rotate_left(start_bit) & lower_mask, 0);
603 let (d, carry) = self.len.overflowing_add(rhs.len << start_bit);
604 return if carry {
605 Self::from_mantissa_with_shl([d, 1].into(), l_shl)
606 } else {
607 Self::from_mantissa_single_with_shl(d, l_shl)
608 };
609 }
610
611 if len == l_digits.len() {
612 debug_assert!(r_digits.len() + start_digit <= l_digits.len());
614 let mut lower = 0;
615 let mut carry = false;
616 for (l, r) in l_digits[start_digit..].iter_mut().zip(&r_digits[..]) {
617 let rot = r.rotate_left(start_bit);
618 (*l, carry) = l.carrying_add(rot & upper_mask | lower, carry);
619 lower = rot & lower_mask;
620 }
621 let i = start_digit + r_digits.len();
622 if let Some(l) = l_digits.get_mut(i) {
623 (*l, carry) = l.carrying_add(lower, carry);
624 lower = 0;
625 for l in &mut l_digits[i + 1..] {
626 (*l, carry) = l.overflowing_add(carry as u64);
627 }
628 }
629 debug_assert_eq!(lower, 0);
630 debug_assert!(!carry);
631 return self;
632 }
633
634 let mut vec = Vec::with_capacity(len);
635 if start_digit >= l_digits.len() {
636 vec.extend_from_slice(l_digits);
637 if start_digit > l_digits.len() {
638 vec.extend((l_digits.len()..start_digit).map(|_| 0));
639 }
640 if start_bit == 0 {
641 vec.extend_from_slice(r_digits);
642 } else {
643 let mut lower = 0;
644 vec.extend(r_digits.iter().map(|&r| {
645 let rot = r.rotate_left(start_bit);
646 rot & upper_mask | mem::replace(&mut lower, rot & lower_mask)
647 }));
648 if lower != 0 {
649 vec.push(lower);
650 }
651 }
652 } else {
653 vec.extend_from_slice(&l_digits[..start_digit]);
654 let mut lower = 0;
655 let mut carry = false;
656 let zipped = l_digits[start_digit..].iter().zip(r_digits.iter());
657 vec.extend(zipped.map(|(l, r)| {
658 let rot = r.rotate_left(start_bit);
659 let res = l.carrying_add(rot & upper_mask | lower, carry);
660 carry = res.1;
661 lower = rot & lower_mask;
662 res.0
663 }));
664 let l_i = start_digit + r_digits.len(); let r_i = l_digits.len() - start_digit; if let Some(l) = l_digits.get(l_i) {
667 let res = l.carrying_add(lower, carry);
668 vec.push(res.0);
669 carry = res.1;
670 lower = 0;
671 vec.extend(l_digits[l_i + 1..].iter().map(|l| {
672 let res = l.overflowing_add(carry as u64);
673 carry = res.1;
674 res.0
675 }));
676 } else if r_i < r_digits.len() {
677 vec.extend(r_digits[r_i..].iter().map(|r| {
678 let rot = r.rotate_left(start_bit);
679 let res = (rot & upper_mask | lower).overflowing_add(carry as u64);
680 lower = rot & lower_mask;
681 carry = res.1;
682 res.0
683 }));
684 }
685 if vec.len() != vec.capacity() {
686 vec.push(lower + carry as u64);
687 } else {
688 debug_assert_eq!(lower + carry as u64, 0);
689 }
690 }
691
692 debug_assert_eq!(vec.capacity(), vec.len());
693 return Self::from_mantissa_with_shl(vec.into_boxed_slice(), l_shl);
694 }
695
696 debug_assert_eq!(l_shl, r_shl);
697
698 let (mut lsd, mut carry) = l_digits[0].overflowing_add(r_digits[0]);
701 let mut i_in = 1;
702 while lsd == 0 {
703 let l = l_digits.get(i_in).copied().unwrap_or_default();
704 let r = r_digits.get(i_in).copied().unwrap_or_default();
705 i_in += 1;
706 debug_assert!(carry);
707 (lsd, carry) = l.carrying_add(r, true);
708 }
709 let bit_shr = shl_amount(lsd);
710 let Some(shl) = l_shl
711 .checked_add(bit_shr as u64)
712 .and_then(|sum| sum.checked_add((i_in as u64 - 1).checked_mul(u64::BITS as u64)?))
713 else {
714 return Self::NAN;
715 };
716 let bit_len = bit_width - shl as u128;
718 debug_assert_ne!(bit_len, 0);
719 let len = bit_len.div_ceil(u64::BITS as u128) as usize;
720
721 let l = l_digits.get(i_in).copied().unwrap_or_default();
722 let r = r_digits.get(i_in).copied().unwrap_or_default();
723 i_in += 1;
724 let (next_lsd, mut carry) = l.carrying_add(r, carry);
725 let mut rot = next_lsd.rotate_right(bit_shr);
726
727 let lower_mask = u64::MAX >> bit_shr;
728 let upper_mask = !lower_mask;
729 let d = (lsd >> bit_shr) | (rot & upper_mask);
730
731 if bit_len <= (u64::BITS + 1) as u128 && rot & lower_mask == 0 {
735 debug_assert!(!carry);
736 return Self::from_mantissa_single_with_shl(d, shl);
737 }
738 debug_assert!(len >= 2);
739
740 if len == l_digits.len() {
741 l_digits[0] = d;
743 let mut i_out = 1;
744 while let Some(l) = l_digits.get(i_in)
745 && let Some(r) = r_digits.get(i_in)
746 {
747 i_in += 1;
748 let res = l.carrying_add(*r, carry);
749 let next_rot = res.0.rotate_right(bit_shr);
750 carry = res.1;
751 l_digits[i_out] = (rot & lower_mask) | (next_rot & upper_mask);
752 i_out += 1;
753 rot = next_rot;
754 }
755
756 if i_in < r_digits.len() {
757 for r in &r_digits[i_in..] {
762 let res = r.overflowing_add(carry as u64);
763 let next_rot = res.0.rotate_right(bit_shr);
764 carry = res.1;
765 l_digits[i_out] = (rot & lower_mask) | (next_rot & upper_mask);
766 i_out += 1;
767 if i_out == len {
768 self.shl = shl;
769 return self;
770 }
771 rot = next_rot;
772 }
773 } else {
774 while let Some(l) = l_digits.get(i_in) {
775 i_in += 1;
776 let res = l.overflowing_add(carry as u64);
777 let next_rot = res.0.rotate_right(bit_shr);
778 carry = res.1;
779 l_digits[i_out] = (rot & lower_mask) | (next_rot & upper_mask);
780 i_out += 1;
781 rot = next_rot;
782 }
783 }
784
785 if bit_shr == 0 {
786 debug_assert_eq!(lower_mask, u64::MAX);
787 l_digits[i_out] = rot;
788 if i_out + 1 != l_digits.len() {
789 i_out += 1;
790 l_digits[i_out] = carry as u64;
791 }
792 } else {
793 l_digits[i_out] = (rot & lower_mask) | (carry as u64).rotate_right(bit_shr);
794 }
795 debug_assert_eq!(i_out + 1, l_digits.len());
796 self.shl = shl;
797 return self;
798 }
799
800 let mut vec = Vec::with_capacity(len);
801 vec.push(d);
802 let (long, short) = if l_digits.len() >= r_digits.len() {
803 (l_digits, r_digits)
804 } else {
805 (r_digits, l_digits)
806 };
807 if i_in < short.len() {
808 let zipped = short[i_in..].iter().zip(&long[i_in..]);
809 vec.extend(zipped.map(|(l, r)| {
810 let res = l.carrying_add(*r, carry);
811 let next_rot = res.0.rotate_right(bit_shr);
812 carry = res.1;
813 (mem::replace(&mut rot, next_rot) & lower_mask) | (next_rot & upper_mask)
814 }));
815 i_in = short.len();
816 }
817 if i_in < long.len() {
818 vec.extend(long[i_in..].iter().map(|x| {
819 let res = x.overflowing_add(carry as u64);
820 let next_rot = res.0.rotate_right(bit_shr);
821 carry = res.1;
822 (mem::replace(&mut rot, next_rot) & lower_mask) | (next_rot & upper_mask)
823 }));
824 }
825
826 if bit_shr == 0 {
827 debug_assert_eq!(lower_mask, u64::MAX);
828 vec.push(rot);
829 if carry {
830 vec.push(1);
831 }
832 } else {
833 let d = (rot & lower_mask) | (carry as u64).rotate_right(bit_shr);
834 if d != 0 {
835 vec.push(d);
836 }
837 }
838 if vec.len() < vec.capacity() {
839 vec.push(0);
840 }
841 debug_assert_eq!(vec.len(), vec.capacity());
842 Self::from_mantissa_with_shl(vec.into_boxed_slice(), shl)
843 }
844}
845
846impl Shl<u64> for Natural {
847 type Output = Self;
848 #[inline]
849 fn shl(mut self, rhs: u64) -> Self {
850 if self.len != 0 {
851 self.shl = self.shl.saturating_add(rhs); }
853 self
854 }
855}
856impl Shl<u32> for Natural {
857 type Output = Self;
858 #[inline(always)]
859 fn shl(self, rhs: u32) -> Self {
860 self.shl(rhs as u64)
861 }
862}
863
864impl Shr<u64> for Natural {
865 type Output = Self;
866 #[inline]
867 fn shr(mut self, rhs: u64) -> Self {
868 if self.shl >= rhs {
869 if self.shl != u64::MAX {
870 self.shl -= rhs;
871 }
872 } else if self.len != 0 {
873 self.shl = u64::MAX; }
875 self
876 }
877}
878impl Shr<u32> for Natural {
879 type Output = Self;
880 #[inline(always)]
881 fn shr(self, rhs: u32) -> Self {
882 self.shr(rhs as u64)
883 }
884}
885
886fn to_u_big(value: &[u64]) -> dashu_int::UBig {
887 match *value {
889 [d] => return d.into(),
890 [d1, d2] => return (d1 as u128 | ((d2 as u128) << 64)).into(),
891 _ => {}
892 }
893
894 const IS_MULTIPLE: bool =
895 mem::size_of::<u64>().is_multiple_of(mem::size_of::<dashu_int::Word>());
896 const SCALE: usize = mem::size_of::<u64>() / mem::size_of::<dashu_int::Word>();
897 const ALIGN_MATCH: bool = mem::align_of::<dashu_int::Word>() <= mem::align_of::<u64>();
898 #[cfg(target_endian = "little")]
900 const FAST_CONV: bool = ALIGN_MATCH && IS_MULTIPLE;
901 #[cfg(target_endian = "big")]
902 const FAST_CONV: bool = ALIGN_MATCH && IS_MULTIPLE && SCALE == 1;
903
904 if FAST_CONV {
905 dashu_int::UBig::from_words(unsafe {
908 std::slice::from_raw_parts(
909 value.as_ptr().cast::<dashu_int::Word>(),
910 value.len() * SCALE,
911 )
912 })
913 } else {
914 #[cfg(target_endian = "big")]
915 let value: Box<[u64]> = value.iter().map(|d| d.swap_bytes()).collect();
916 #[cfg(target_endian = "big")]
917 let value = value.as_slice();
918
919 dashu_int::UBig::from_le_bytes(unsafe {
921 std::slice::from_raw_parts(value.as_ptr().cast::<u8>(), mem::size_of_val(value))
922 })
923 }
924}
925
926impl TryFrom<&Natural> for dashu_int::UBig {
927 type Error = super::NotRepresentable;
928
929 fn try_from(value: &Natural) -> Result<Self, Self::Error> {
930 if value.shl > std::cmp::min(1 << 40, usize::MAX as u64) {
931 return Err(super::NotRepresentable); }
933 let mut mantissa = to_u_big(value.mantissa());
934 mantissa <<= value.shl as usize;
935 Ok(mantissa)
936 }
937}
938
939impl TryFrom<&Natural> for u128 {
940 type Error = super::NotRepresentable;
941
942 fn try_from(value: &Natural) -> Result<Self, Self::Error> {
943 if value.shl < u128::BITS as u64
944 && let mantissa = value.mantissa_raw()
945 && mantissa.len() <= 3
946 && mantissa.len() as u32 * u64::BITS - mantissa.last().unwrap().leading_zeros()
947 + value.shl as u32
948 <= u128::BITS
949 {
950 let upper = mantissa.get(1).copied().unwrap_or_default();
951 return Ok(mantissa[0] as u128 | ((upper as u128) << u64::BITS));
952 }
953 Err(super::NotRepresentable)
954 }
955}
956impl TryFrom<&Natural> for u64 {
957 type Error = super::NotRepresentable;
958
959 fn try_from(value: &Natural) -> Result<Self, Self::Error> {
960 if value.shl < u64::BITS as u64
961 && value.ptr == DANGLING
962 && value.shl as u32 <= value.len.leading_zeros()
963 {
964 return Ok(value.len << value.shl);
965 }
966 Err(super::NotRepresentable)
967 }
968}
969impl From<&Natural> for f64 {
970 fn from(value: &Natural) -> Self {
971 const ZERO_OFFSET: u32 = 1023;
972 const MANTISSA_BITS: u32 = f64::MANTISSA_DIGITS - 1; const EXP_BITS: u32 = u64::BITS - MANTISSA_BITS - 1;
974
975 if value.is_nan() {
976 return f64::NAN;
977 }
978 let mantissa = value.mantissa();
979 let msd = *mantissa.last().unwrap();
980 if msd == 0 {
981 return 0.;
982 }
983 let leading_zeros = msd.leading_zeros();
984 let bit_width = (mantissa.len() as u64)
985 .saturating_mul(u64::BITS as u64)
986 .saturating_add(value.shl)
987 - leading_zeros as u64;
988 if bit_width > f64::MAX_EXP as u64 {
990 return f64::INFINITY;
991 }
992 let exp = bit_width as u32 + ZERO_OFFSET - 1;
993 debug_assert!(exp < (1 << EXP_BITS) - 1);
994
995 let msd2 = if let [.., msd2, _] = *mantissa {
996 msd2
997 } else {
998 0
999 };
1000 let frac_trunc_msb = if msd != 1 {
1003 msd << (leading_zeros + 1) | msd2 >> (u64::BITS - (leading_zeros + 1))
1004 } else {
1005 msd2
1006 };
1007 let shr = u64::BITS - MANTISSA_BITS;
1008 let frac_trunc = frac_trunc_msb >> shr;
1009 let frac_rounded = frac_trunc
1010 + if bit_width - value.shl == f64::MANTISSA_DIGITS as u64 + 1 {
1011 frac_trunc & 1 } else {
1013 (frac_trunc_msb >> (shr - 1)) & 1
1014 };
1015 debug_assert!(frac_rounded <= 1 << MANTISSA_BITS);
1016 f64::from_bits(((exp as u64) << MANTISSA_BITS) + frac_rounded)
1019 }
1020}
1021
1022fn fmt_nan(f: &mut fmt::Formatter<'_>) -> fmt::Result {
1023 if let Some(width) = f.width()
1024 && width >= 2
1025 {
1026 let w = width - 1;
1027 let c = f.fill();
1028 match f.align() {
1029 Some(fmt::Alignment::Left) => {
1030 f.write_char('?')?;
1031 for _ in 0..w {
1032 f.write_char(c)?;
1033 }
1034 }
1035 Some(fmt::Alignment::Center) => {
1036 let first_half = w / 2;
1037 for _ in 0..first_half {
1038 f.write_char(c)?;
1039 }
1040 f.write_char('?')?;
1041 for _ in 0..(w - first_half) {
1042 f.write_char(c)?;
1043 }
1044 }
1045 _ => {
1046 for _ in 0..w {
1047 f.write_char(c)?;
1048 }
1049 f.write_char('?')?;
1050 }
1051 }
1052 Ok(())
1053 } else {
1054 f.write_char('?')
1055 }
1056}
1057
1058impl fmt::Display for Natural {
1059 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1060 match dashu_int::UBig::try_from(self) {
1061 Ok(num) => num.fmt(f),
1062 Err(_) => fmt_nan(f),
1063 }
1064 }
1065}
1066
1067#[inline]
1070fn pad_integral(
1071 f: &mut fmt::Formatter<'_>,
1072 digits: u128,
1073 prefix: &str,
1074 write_digits: impl FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result,
1075) -> fmt::Result {
1076 let prefix_width = f.alternate() as usize * prefix.len() + f.sign_plus() as usize;
1077 let min_digits = f.width().unwrap_or(0).saturating_sub(prefix_width);
1078 let mut pad = match usize::try_from(digits) {
1079 Ok(digits) => min_digits.saturating_sub(digits),
1080 Err(_) => 0,
1081 };
1082
1083 if pad != 0 && f.sign_aware_zero_pad() {
1084 for _ in 0..pad {
1085 f.write_char('0')?;
1086 }
1087 pad = 0;
1088 }
1089
1090 if f.sign_plus() {
1091 f.write_char('+')?;
1092 }
1093 if f.alternate() {
1094 f.write_str(prefix)?;
1095 }
1096
1097 let fill_char = f.fill();
1098 if pad != 0 {
1099 let pad_front = match f.align() {
1100 Some(fmt::Alignment::Left) => 0,
1101 Some(fmt::Alignment::Center) => pad / 2,
1102 _ => pad,
1103 };
1104 pad -= pad_front;
1105 for _ in 0..pad_front {
1106 f.write_char(fill_char)?;
1107 }
1108 }
1109
1110 write_digits(f)?;
1111
1112 for _ in 0..pad {
1113 f.write_char(fill_char)?;
1114 }
1115
1116 Ok(())
1117}
1118
1119impl fmt::Binary for Natural {
1120 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1121 if self.is_nan() {
1122 return fmt_nan(f);
1123 }
1124
1125 let mantissa = self.mantissa();
1126 let bit_width = bit_width(mantissa, self.shl);
1127
1128 pad_integral(f, bit_width, "0b", move |f| {
1129 let msd = *mantissa.last().unwrap();
1130 if msd == 0 {
1131 return f.write_char('0');
1132 }
1133
1134 let mut pos = u64::BITS - msd.leading_zeros();
1135 for &d in mantissa.iter().rev() {
1136 while pos != 0 {
1137 pos -= 1;
1138 f.write_char(if d & (1 << pos) != 0 { '1' } else { '0' })?;
1139 }
1140 pos = u64::BITS;
1141 }
1142
1143 for _ in 0..self.shl {
1144 f.write_char('0')?;
1145 }
1146 Ok(())
1147 })
1148 }
1149}
1150
1151impl Natural {
1152 #[inline] fn fmt_pow2(
1154 &self,
1155 f: &mut fmt::Formatter<'_>,
1156 bits_per_digit: u32,
1157 prefix: &str,
1158 to_char: impl Fn(u8) -> char,
1159 ) -> fmt::Result {
1160 debug_assert!(bits_per_digit < u64::BITS);
1161 if self.is_nan() {
1162 return fmt_nan(f);
1163 }
1164
1165 let mut mantissa = self.mantissa();
1166 let bit_width = bit_width(mantissa, self.shl);
1167 let digits = bit_width.div_ceil(bits_per_digit as u128);
1168 let rem_bits = (bit_width % bits_per_digit as u128) as u32;
1169
1170 pad_integral(f, digits, prefix, move |f| {
1171 let mut msd = *mantissa.split_off_last().unwrap();
1172 if msd == 0 {
1173 return f.write_char('0');
1174 }
1175 let rem_bits = if rem_bits == 0 {
1179 bits_per_digit
1180 } else {
1181 rem_bits
1182 };
1183 let mut offset = (u64::BITS - msd.leading_zeros()) as i32 - rem_bits as i32;
1184 let mut done = false;
1185 while !done {
1186 let digit = if offset >= 0 {
1187 msd >> offset
1188 } else {
1189 let upper = msd << offset.abs();
1190 offset += u64::BITS as i32;
1191
1192 if let Some(v) = mantissa.split_off_last() {
1193 msd = *v;
1194 upper | (msd >> offset)
1195 } else if offset == (u64::BITS - bits_per_digit) as i32 {
1196 break;
1197 } else {
1198 done = true;
1199 upper
1200 }
1201 } & ((1 << bits_per_digit) - 1);
1202 f.write_char(to_char(digit as u8))?;
1203 offset -= bits_per_digit as i32;
1204 }
1205
1206 let trailing_zeros = self.shl / bits_per_digit as u64;
1207 for _ in 0..trailing_zeros {
1208 f.write_char('0')?;
1209 }
1210
1211 Ok(())
1212 })
1213 }
1214}
1215
1216impl fmt::Octal for Natural {
1217 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1218 self.fmt_pow2(f, 3, "0o", |d| (b'0' + d) as char)
1219 }
1220}
1221impl fmt::LowerHex for Natural {
1222 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1223 self.fmt_pow2(f, 4, "0x", |d| {
1224 (if d < 10 { b'0' + d } else { b'a' + (d - 10) }) as char
1225 })
1226 }
1227}
1228impl fmt::UpperHex for Natural {
1229 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1230 self.fmt_pow2(f, 4, "0x", |d| {
1231 (if d < 10 { b'0' + d } else { b'A' + (d - 10) }) as char
1232 })
1233 }
1234}
1235
1236impl fmt::Debug for Natural {
1237 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1238 if self.is_nan() {
1239 return fmt_nan(f);
1240 }
1241
1242 let mantissa = self.mantissa();
1243 if let [d] = mantissa {
1244 d.fmt(f)?;
1245 } else {
1246 to_u_big(mantissa).fmt(f)?;
1247 }
1248 f.write_str(" * 2^")?;
1249 self.shl.fmt(f)
1250 }
1251}
1252
1253#[cfg(test)]
1254mod test {
1255 use super::Natural;
1256 use std::fmt::Write as _;
1257
1258 #[test]
1259 fn test_from_clone_and_shift_small() {
1260 let zero = Natural::from(0u32);
1261 zero.check_inv();
1262 assert_eq!(zero, Natural::ZERO);
1263
1264 let clone = zero.clone();
1265 clone.check_inv();
1266 assert_eq!(clone, Natural::ZERO);
1267
1268 let mut clone = clone << 1u64;
1269 clone.check_inv();
1270 assert_eq!(clone, Natural::ZERO);
1271
1272 let one = Natural::from(1u64);
1273 one.check_inv();
1274 assert_ne!(one, Natural::ZERO);
1275 assert!(one > Natural::ZERO);
1276
1277 let two = Natural::from(2u64);
1278 two.check_inv();
1279 assert_ne!(two, one);
1280 assert!(two > one);
1281
1282 clone.clone_from(&one);
1283 clone.check_inv();
1284 assert_eq!(clone, one);
1285
1286 let clone = clone << 1u32;
1287 clone.check_inv();
1288 assert_eq!(clone, two);
1289 }
1290
1291 #[test]
1292 fn test_from_le_digits() {
1293 for slice in [[].as_slice(), &[0], &[0, 0]] {
1294 let num = Natural::from_le_digits(slice);
1295 num.check_inv();
1296 assert_eq!(num, Natural::ZERO);
1297 }
1298
1299 let one = Natural::from(1u32);
1300 for slice in [[1].as_slice(), &[1, 0]] {
1301 let num = Natural::from_le_digits(slice);
1302 num.check_inv();
1303 assert_eq!(num, one);
1304 }
1305
1306 let two = Natural::from(2u32);
1307 let num = Natural::from_le_digits(&[2]);
1308 num.check_inv();
1309 assert_eq!(num, two);
1310
1311 let a = one.clone() << u64::BITS;
1312 let b = Natural::from_le_digits(&[0, 1]);
1313 b.check_inv();
1314 assert_eq!(a, b);
1315
1316 let a = Natural::from(0b11u32) << (2 * u64::BITS - 1);
1317 let b = Natural::from_le_digits(&[0, 1 << (u64::BITS - 1), 1]);
1318 b.check_inv();
1319 assert_eq!(a, b);
1320
1321 let half_bits = u64::BITS / 2;
1322 let a = Natural::from_le_digits(&[!0 << half_bits, !0, !0 >> half_bits]);
1323 a.check_inv();
1324 let b = Natural::from_le_digits(&[!0, !0]);
1325 b.check_inv();
1326 let b = b << half_bits;
1327 b.check_inv();
1328 assert_eq!(a, b);
1329
1330 let half1_bits = u64::BITS / 2 - 1;
1331 let a = Natural::from_le_digits(&[!0 << half1_bits, !0, !0 >> half1_bits]);
1332 a.check_inv();
1333 let b = Natural::from_le_digits(&[!0, !0, 0b11]);
1334 b.check_inv();
1335 let b = b << half1_bits;
1336 b.check_inv();
1337 assert_eq!(a, b);
1338 }
1339
1340 #[test]
1341 fn test_add() {
1342 for shl in [0, 1, u64::BITS - 1] {
1343 let case = |lhs: Natural, rhs: Natural, sum: Natural| {
1344 let lhs = lhs << shl;
1345 let rhs = rhs << shl;
1346 let expected = sum << shl;
1347 let actual = lhs.clone() + rhs.clone();
1348 actual.check_inv();
1349 assert_eq!(actual, expected);
1350 let actual_rev = rhs + lhs;
1351 actual_rev.check_inv();
1352 assert_eq!(actual_rev, expected);
1353 };
1354
1355 case(1u32.into(), Natural::ZERO, 1u32.into());
1357 case(u64::MAX.into(), Natural::ZERO, u64::MAX.into());
1358 case(
1359 Natural::from_le_digits(&[1, 1]),
1360 Natural::ZERO,
1361 Natural::from_le_digits(&[1, 1]),
1362 );
1363
1364 case(1u32.into(), 1u32.into(), 2u32.into());
1366
1367 let a = Natural::from_le_digits(&[!0, 1]);
1368 case(a.clone(), a.clone(), a << 1u32);
1369
1370 case(
1371 u64::MAX.into(),
1372 1u32.into(),
1373 Natural::from(1u32) << u64::BITS,
1374 );
1375
1376 case(
1377 u64::MAX.into(),
1378 u64::MAX.into(),
1379 Natural::from_le_digits(&[u64::MAX << 1, 1]),
1380 );
1381
1382 case(
1383 u64::MAX.into(),
1384 Natural::from_le_digits(&[1, !0, 1]),
1385 Natural::from(1u32) << (2 * u64::BITS + 1),
1386 );
1387
1388 case(
1389 Natural::from_le_digits(&[1, 1 << (u64::BITS - 1)]),
1390 Natural::from_le_digits(&[u64::MAX, 1 << (u64::BITS - 1)]),
1391 Natural::from_le_digits(&[1, 1]) << u64::BITS,
1392 );
1393
1394 case(
1395 Natural::from_le_digits(&[1, 1]),
1396 Natural::from_le_digits(&[!0, !0, 1]),
1397 Natural::from_le_digits(&[1, 0b10]) << u64::BITS,
1398 );
1399
1400 case(
1401 Natural::from_le_digits(&[1, 1]),
1402 Natural::from_le_digits(&[!0, !0, !0]),
1403 Natural::from_le_digits(&[1, 0, 1]) << u64::BITS,
1404 );
1405
1406 case(
1407 Natural::from_le_digits(&[1, 1 << (u64::BITS - 1)]),
1408 Natural::from_le_digits(&[!0, !0, !0, 1]),
1409 Natural::from_le_digits(&[1, 0b100]) << (2 * u64::BITS - 1),
1410 );
1411
1412 case(
1413 Natural::from_le_digits(&[1, 1 << (u64::BITS - 1)]),
1414 Natural::from_le_digits(&[!0, !0, !0, u64::MAX >> 1]),
1415 Natural::from_le_digits(&[1, 0, 1]) << (2 * u64::BITS - 1),
1416 );
1417
1418 case(
1419 Natural::from_le_digits(&[1, 0, 1]),
1420 1u32.into(),
1421 Natural::from_le_digits(&[2, 0, 1]),
1422 );
1423
1424 case(1u32.into(), 2u32.into(), 3u32.into());
1426
1427 let max_bit: u64 = 1 << (u64::BITS - 1);
1428 case(
1429 (1 | max_bit).into(),
1430 (1 ^ u64::MAX).into(),
1431 Natural::from_le_digits(&[u64::MAX ^ max_bit, 1]),
1432 );
1433
1434 case(
1435 Natural::from_le_digits(&[0, 1]),
1436 1u32.into(),
1437 Natural::from_le_digits(&[1, 1]),
1438 );
1439
1440 case(
1441 Natural::from_le_digits(&[0, 2]),
1442 1u32.into(),
1443 Natural::from_le_digits(&[1, 2]),
1444 );
1445
1446 case(
1447 Natural::from_le_digits(&[1, 1]),
1448 Natural::from_le_digits(&[0, 2]),
1449 Natural::from_le_digits(&[1, 3]),
1450 );
1451
1452 case(
1453 Natural::from_le_digits(&[1, 1]),
1454 Natural::from_le_digits(&[0, 2, 1]),
1455 Natural::from_le_digits(&[1, 3, 1]),
1456 );
1457
1458 case(
1459 Natural::from_le_digits(&[1, 1]),
1460 Natural::from_le_digits(&[0, 2, 2]),
1461 Natural::from_le_digits(&[1, 3, 2]),
1462 );
1463
1464 case(
1465 Natural::from_le_digits(&[1, u64::MAX]),
1466 Natural::from_le_digits(&[0, 2, 1]),
1467 Natural::from_le_digits(&[1, 1, 2]),
1468 );
1469
1470 case(
1471 Natural::from_le_digits(&[!0]),
1472 Natural::from_le_digits(&[2, !0]),
1473 Natural::from_le_digits(&[1, 0, 1]),
1474 );
1475 }
1476 }
1477
1478 #[test]
1479 fn test_to_f64() {
1480 for val in 0..0x10000u64 {
1481 assert_eq!(f64::from(&Natural::from(val)), val as f64);
1482 }
1483 for shl in 52..60 {
1484 for val in ((1u64 << shl) - 0xf)..=((1 << shl) + 0xf) {
1485 assert_eq!(f64::from(&Natural::from(val)), val as f64, "{val}");
1486 }
1487 }
1488 assert_eq!(
1489 f64::from(&Natural::from_mantissa_single_with_shl(1, 1023)),
1490 2f64.powi(1023),
1491 );
1492 assert_eq!(
1493 f64::from(&Natural::from_mantissa_single_with_shl(1, 1024)),
1494 f64::INFINITY,
1495 );
1496 }
1497
1498 #[test]
1499 fn fmt_bin() -> std::fmt::Result {
1500 let mut buf = String::with_capacity(128);
1501
1502 write!(buf, "{:b}", Natural::from(0u32))?;
1503 assert_eq!(&buf, "0");
1504 buf.clear();
1505
1506 write!(buf, "{:#b}", Natural::from(0u32))?;
1507 assert_eq!(&buf, "0b0");
1508 buf.clear();
1509
1510 write!(buf, "{:b}", Natural::from(1u32))?;
1511 assert_eq!(&buf, "1");
1512 buf.clear();
1513
1514 write!(buf, "{:b}", Natural::from(2u32))?;
1515 assert_eq!(&buf, "10");
1516 buf.clear();
1517
1518 write!(buf, "{:b}", Natural::from(3u32))?;
1519 assert_eq!(&buf, "11");
1520 buf.clear();
1521
1522 write!(buf, "{:b}", Natural::from(4u32))?;
1523 assert_eq!(&buf, "100");
1524 buf.clear();
1525
1526 write!(buf, "{:b}", Natural::from_le_digits(&[1, 1]))?;
1527 assert_eq!(buf, format!("{:b}", (1u128 << 64) | 1));
1528 buf.clear();
1529
1530 Ok(())
1531 }
1532
1533 #[test]
1534 fn fmt_oct() -> std::fmt::Result {
1535 let mut buf = String::with_capacity(16);
1536
1537 write!(buf, "{:o}", Natural::from(0u32))?;
1538 assert_eq!(&buf, "0");
1539 buf.clear();
1540
1541 write!(buf, "{:#o}", Natural::from(0u32))?;
1542 assert_eq!(&buf, "0o0");
1543 buf.clear();
1544
1545 write!(buf, "{:o}", Natural::from(1u32))?;
1546 assert_eq!(&buf, "1");
1547 buf.clear();
1548
1549 write!(buf, "{:o}", Natural::from(9u32))?;
1550 assert_eq!(&buf, "11");
1551 buf.clear();
1552
1553 write!(buf, "{:o}", Natural::from(0o71u32))?;
1554 assert_eq!(&buf, "71");
1555 buf.clear();
1556
1557 write!(buf, "{:o}", Natural::from(0o72u32))?;
1558 assert_eq!(&buf, "72");
1559 buf.clear();
1560
1561 write!(buf, "{:o}", Natural::from(0o74u32))?;
1562 assert_eq!(&buf, "74");
1563 buf.clear();
1564
1565 Ok(())
1566 }
1567
1568 #[test]
1569 fn fmt_hex() -> std::fmt::Result {
1570 let mut buf = String::with_capacity(16);
1571
1572 write!(buf, "{:x}", Natural::from(0u32))?;
1573 assert_eq!(&buf, "0");
1574 buf.clear();
1575
1576 write!(buf, "{:#x}", Natural::from(0u32))?;
1577 assert_eq!(&buf, "0x0");
1578 buf.clear();
1579
1580 write!(buf, "{:x}", Natural::from(1u32))?;
1581 assert_eq!(&buf, "1");
1582 buf.clear();
1583
1584 write!(buf, "{:x}", Natural::from(0xau32))?;
1585 assert_eq!(&buf, "a");
1586 buf.clear();
1587
1588 write!(buf, "{:X}", Natural::from(0xau32))?;
1589 assert_eq!(&buf, "A");
1590 buf.clear();
1591
1592 write!(buf, "{:x}", Natural::from(0xf1u32))?;
1593 assert_eq!(&buf, "f1");
1594 buf.clear();
1595
1596 write!(buf, "{:x}", Natural::from(0xf2u32))?;
1597 assert_eq!(&buf, "f2");
1598 buf.clear();
1599
1600 write!(buf, "{:x}", Natural::from(0xf4u32))?;
1601 assert_eq!(&buf, "f4");
1602 buf.clear();
1603
1604 write!(buf, "{:x}", Natural::from(0xf8u32))?;
1605 assert_eq!(&buf, "f8");
1606 buf.clear();
1607
1608 Ok(())
1609 }
1610}