Skip to main content

a/math/numbers/
radix.rs

1//! Numbers as text in a radix from 2 to 36: [`Number::to_str_radix`], [`Number::from_str_radix`],
2//! and the formatting traits `Display` (decimal), `LowerHex`, `UpperHex`, `Octal` and `Binary`.
3//!
4//! The text is the sign and the digits of the magnitude, the most significant first, with `-` for
5//! a negative number and nothing for the others: `-255` is `-ff` in hexadecimal, not the two's
6//! complement that the formatting of a primitive integer gives. Digits above 9 are the letters,
7//! lower-case when written, either case when read.
8//!
9//! In a radix that is a power of two, each digit is a group of bits of the magnitude, and the
10//! text is written or read in one pass over the bytes, where they are: hexadecimal two digits a
11//! byte from a table, binary eight a byte spread by a multiplication, the others in groups of
12//! bytes. In another radix, the magnitude goes through the largest power `b` of the radix that
13//! fits in a limb, `10^19` for decimal, whose remainders are blocks of digits.
14//!
15//! Written, a short magnitude is divided by `b` again and again, limb by limb, with the
16//! reciprocal of `b` (see [`Divisor`]). Each limb of a division waits for the remainder of the
17//! limb above it, about ten cycles, and a division waits for the quotient of the one before it;
18//! but the next division can start on the top limb of that quotient as soon as it is known, so
19//! the divisions run in groups of up to [`PASSES`], each a limb behind the one before it, and the
20//! core overlaps their chains. The blocks of decimal digits are made eight digits at a time in the
21//! lanes of a `u64`, by multiplications, with no division. A long magnitude is split by divide
22//! and conquer, divided by `b^(2^i)` for the largest `i` that halves it, and the quotient and the
23//! remainder written the same way, the remainder with as many digits as `b^(2^i)` has places,
24//! zeros at the front. Up to two limbs of decimal take a path of their own, in registers.
25//!
26//! Read, decimal digits are checked and turned into values eight at a time in the lanes of a
27//! `u64`, other radices a digit at a time; up to 38 decimal digits are read into a `u128`, and the
28//! blocks of longer text multiplied in, `x b + v`, a pass over the limbs each, in place. The
29//! passes run in waves as the divisions do, [`READ_PASSES`] at a time. Long text is split in
30//! halves, the upper one multiplied by the power of `b` of the lower one's places and the lower
31//! one added. The powers of divide and conquer, both ways, drop their zero bytes at the bottom
32//! (`10^19` is `5^19 2^19`, so a third of the bytes of its powers are zeros), and the part of a
33//! number below them is set aside instead of divided or multiplied.
34
35use super::add::{read, read_small, write};
36use super::div::{divide_2by1, reciprocal};
37use super::mul::{Operand, Product, to_limbs};
38use super::{ByteOrder, Divisor, Number};
39use core::fmt;
40use core::mem::MaybeUninit;
41
42/// The digits of the radices up to 36.
43const DIGITS: &[u8; 36] = b"0123456789abcdefghijklmnopqrstuvwxyz";
44
45/// From this many limbs, a magnitude is written by divide and conquer. Measured on an Apple M4
46/// Max in decimal, 80 took at most 5.5% longer than the best of 40, 64, 80, 100 and 150 from 384
47/// bytes to 4 KiB, where 64 took up to 20% longer (at 512 bytes), 100 up to 10% (1.5 KiB), 40 36%
48/// (384 bytes) and 150 16% (2 KiB). It weighs the waves of divisions against the division of a
49/// long magnitude by a power: when the division gets faster, it falls.
50const WRITE_SPLIT: usize = 80;
51
52/// From this many blocks of text, it is read by divide and conquer. Measured on an Apple M4 Max in
53/// decimal, 220 took at most 7% longer than the best of 160, 220 and 300 from 1 to 64 KiB, the
54/// others up to 14% longer at some length; 100 took 33% longer for 1 KiB, and 600 15% to 35%
55/// longer from 3 to 12 KiB. It weighs the waves of passes against the products of halves, by
56/// Karatsuba's method from 24 limbs: when the multiplication gets faster, it falls.
57const READ_SPLIT: usize = 220;
58
59/// The most divisions by `b` that run at once when a magnitude is written: see [`divide_blocks`].
60/// Measured on an Apple M4 Max in decimal with one size of group for every length, 6 and 8 were
61/// within 4% of each other from 128 to 256 bytes, and up to 12% faster than 4, which was the best
62/// for 3 to 8 limbs, as smaller groups waste fewer divisions above the top; 2 was slower from 24
63/// bytes. So the groups shrink with the limbs left.
64const PASSES: usize = 8;
65
66/// The largest power of ten in a limb, `10^19`, whose remainders are the blocks of decimal digits.
67/// Its top bit is set, so it needs no shift to divide by.
68const TEN_19: u64 = 10_000_000_000_000_000_000;
69
70/// The reciprocal of [`TEN_19`], `floor((B^2 - 1) / 10^19) - B`, as [`reciprocal`] computes it.
71const TEN_19_INVERSE: u64 = (u128::MAX / TEN_19 as u128 - (1 << 64)) as u64;
72
73/// Text of up to this many digits is written in a buffer on the stack by the formatting traits.
74const STACK_TEXT: usize = 160;
75
76/// Text of up to this many blocks is read into limbs on the stack.
77const STACK_BLOCKS: usize = 64;
78
79/// The blocks multiplied in at once when text is read: see [`mul_add_group`]. Measured on an Apple
80/// M4 Max for 1 to 4 KiB of decimal text, 6 and 8 took 0.83 cycles a limb a block, 4 0.88 and 2
81/// 1.2, against 1.24 by a pass of the multiplication's kernel and an addition of the block.
82const READ_PASSES: usize = 6;
83
84/// From this many limbs, blocks are multiplied in [`READ_PASSES`] at a time: below, the waves
85/// that start and end a group outweigh the passes.
86const READ_WAVES: usize = 2;
87
88/// The largest power of `radix` that fits in a limb, `b = radix^k`, and its exponent `k`: the
89/// places of the blocks of digits.
90fn block(radix: u32) -> (u64, usize) {
91    let (mut b, mut k) = (u64::from(radix), 1);
92    while let Some(next) = b.checked_mul(u64::from(radix)) {
93        b = next;
94        k += 1;
95    }
96    (b, k)
97}
98
99/// Panics for a radix outside `2..=36`, as the primitive integers' `from_str_radix` does.
100#[track_caller]
101fn check_radix(radix: u32) {
102    assert!(
103        (2..=36).contains(&radix),
104        "from_str_radix_int: must lie in the range `[2, 36]` - found {radix}"
105    );
106}
107
108impl Number {
109    /// Returns the number as text in `radix`: `-` for a negative number, then the digits of the
110    /// magnitude, the most significant first, without zeros in front, letters lower-case; `0` for
111    /// zero.
112    ///
113    /// # Panics
114    ///
115    /// When `radix` is not from 2 to 36.
116    ///
117    /// # Examples
118    ///
119    /// ```
120    /// use a::math::numbers::{ByteOrder, Number};
121    ///
122    /// let n = Number::new_from_i32(-255, ByteOrder::BigEndian);
123    /// assert_eq!(n.to_str_radix(16), "-ff");
124    /// assert_eq!(n.to_str_radix(10), "-255");
125    /// assert_eq!(n.to_str_radix(2), "-11111111");
126    /// ```
127    #[track_caller]
128    pub fn to_str_radix(&self, radix: u32) -> String {
129        check_radix(radix);
130        let x = Operand::of(self);
131        let sign = usize::from(self.negative && x.significant != 0);
132        let mut out =
133            Vec::<u8>::with_capacity(digits_bound(x.significant, radix).saturating_add(sign));
134        // SAFETY: the vector has room for the sign and the digits, which are all written before
135        // the length is set; they are ASCII, so the string is UTF-8. `self` is borrowed while it
136        // is read.
137        unsafe {
138            let p = out.as_mut_ptr();
139            *p = b'-';
140            let n = write_magnitude(x, radix, p.add(sign));
141            out.set_len(sign + n);
142            String::from_utf8_unchecked(out)
143        }
144    }
145
146    /// Reads a number from text in `radix`: an optional sign, `+` or `-`, then at least one digit,
147    /// from `0` to the radix's last, letters in either case, with no other characters, as the
148    /// primitive integers' `from_str_radix` reads; zeros in front count for nothing. The number is
149    /// built in `byte_order`, in the shortest form; `-0` is zero, not negative.
150    ///
151    /// # Errors
152    ///
153    /// [`ParseNumberError`] of kind [`NumberErrorKind::Empty`] for empty text, and
154    /// [`NumberErrorKind::InvalidDigit`] for a character that is not a digit of the radix, or a
155    /// sign alone.
156    ///
157    /// # Panics
158    ///
159    /// When `radix` is not from 2 to 36.
160    ///
161    /// # Examples
162    ///
163    /// ```
164    /// use a::math::numbers::{ByteOrder, Number, NumberErrorKind};
165    ///
166    /// let n = Number::from_str_radix("-FF", 16, ByteOrder::BigEndian).unwrap();
167    /// assert_eq!(n.value, [0xFF]);
168    /// assert!(n.is_negative());
169    ///
170    /// // 10^21 = 0x36_35C9_ADC5_DEA0_0000.
171    /// let n = Number::from_str_radix("1000000000000000000000", 10, ByteOrder::LittleEndian);
172    /// assert_eq!(n.unwrap().value, [0, 0, 0xA0, 0xDE, 0xC5, 0xAD, 0xC9, 0x35, 0x36]);
173    ///
174    /// let error = Number::from_str_radix("12a", 10, ByteOrder::BigEndian).err().unwrap();
175    /// assert_eq!(*error.kind(), NumberErrorKind::InvalidDigit);
176    /// ```
177    #[track_caller]
178    pub fn from_str_radix(
179        src: &str,
180        radix: u32,
181        byte_order: ByteOrder,
182    ) -> Result<Number, ParseNumberError> {
183        check_radix(radix);
184        let bytes = src.as_bytes();
185        let (negative, digits) = match bytes.first() {
186            None => return Err(error(NumberErrorKind::Empty)),
187            Some(b'-') => (true, &bytes[1..]),
188            Some(b'+') => (false, &bytes[1..]),
189            Some(_) => (false, bytes),
190        };
191        if digits.is_empty() {
192            return Err(error(NumberErrorKind::InvalidDigit));
193        }
194        if radix == 10 {
195            read_decimal(digits, negative, byte_order)
196        } else if radix.is_power_of_two() {
197            read_bits(digits, radix.trailing_zeros(), negative, byte_order)
198        } else {
199            read_long(digits, radix, negative, byte_order)
200        }
201        .ok_or(error(NumberErrorKind::InvalidDigit))
202    }
203}
204
205/// The error of the kind `kind`.
206#[cold]
207fn error(kind: NumberErrorKind) -> ParseNumberError {
208    ParseNumberError { kind }
209}
210
211// Writing
212
213/// The most digits that a magnitude of `bytes` significant bytes has in `radix`, at least one:
214/// `log_radix(2)` digits a bit, rounded up, and one more. Computed in 64 bits, so that it does not
215/// wrap on 32-bit targets, and `usize::MAX` when it does not fit, which no vector can hold.
216fn digits_bound(bytes: usize, radix: u32) -> usize {
217    let bits = 8 * bytes as u64;
218    let digits = if radix == 10 {
219        // log10(2) < 1234 / 4096.
220        ((bits * 1234) >> 12) + 1
221    } else {
222        // At least `floor(log2(radix))` bits a digit.
223        bits / u64::from(31 - radix.leading_zeros()) + 1
224    };
225    usize::try_from(digits).unwrap_or(usize::MAX)
226}
227
228/// Writes the digits of the magnitude of the operand `x` in `radix` at `dst`, without zeros in
229/// front, `0` for zero, and returns how many.
230///
231/// # Safety
232///
233/// The operand's vector must be valid for reads, and `dst` for writing
234/// [`digits_bound`]`(x.significant, radix)` bytes.
235unsafe fn write_magnitude(x: Operand, radix: u32, dst: *mut u8) -> usize {
236    // SAFETY: as the caller guarantees.
237    unsafe {
238        if x.significant == 0 {
239            *dst = b'0';
240            return 1;
241        }
242        if radix.is_power_of_two() {
243            return write_bits(x, radix.trailing_zeros(), dst);
244        }
245        let n = x.significant.div_ceil(8);
246        if radix == 10 && n <= 2 {
247            let order = if x.big_endian {
248                ByteOrder::BigEndian
249            } else {
250                ByteOrder::LittleEndian
251            };
252            return write_u128(read_small(significant(x), order), dst);
253        }
254        if n < WRITE_SPLIT {
255            // The limbs, and the room above them that the divisions write quotients of zero into.
256            let mut u = [MaybeUninit::<u64>::uninit(); WRITE_SPLIT + PASSES];
257            let u = u.as_mut_ptr().cast::<u64>();
258            to_limbs(x, u);
259            return write_limbs(u, n, radix, None, dst);
260        }
261        let mut powers = Vec::new();
262        write_split(le_number(x), radix, None, dst, &mut powers, true)
263    }
264}
265
266/// The significant bytes of the operand `x`, in its byte order.
267///
268/// # Safety
269///
270/// The operand's vector must be valid for reads while the slice is alive.
271unsafe fn significant<'a>(x: Operand) -> &'a [u8] {
272    let start = if x.big_endian {
273        x.len - x.significant
274    } else {
275        0
276    };
277    // SAFETY: the significant bytes lie in the operand's vector.
278    unsafe { core::slice::from_raw_parts(x.ptr.add(start), x.significant) }
279}
280
281/// The magnitude of the operand `x` as a little-endian number in the shortest form.
282///
283/// # Safety
284///
285/// The operand's vector must be valid for reads.
286unsafe fn le_number(x: Operand) -> Number {
287    // SAFETY: as the caller guarantees.
288    let bytes = unsafe { significant(x) };
289    let le = if x.big_endian {
290        bytes.iter().rev().copied().collect()
291    } else {
292        bytes.to_vec()
293    };
294    Number {
295        value: le,
296        negative: false,
297        byte_order: ByteOrder::LittleEndian,
298    }
299}
300
301/// Writes the decimal digits of `x`, not zero, at `dst`, without zeros in front, and returns how
302/// many: from 1 to 20.
303///
304/// # Safety
305///
306/// `dst` must be valid for writing as many bytes as `x` has digits.
307#[inline]
308unsafe fn write_u64(x: u64, dst: *mut u8) -> usize {
309    // SAFETY: as the caller guarantees.
310    unsafe {
311        if x >= TEN_19 {
312            // 20 digits: `x < 2 10^19`.
313            *dst = b'1';
314            write_block(x - TEN_19, dst.add(1));
315            20
316        } else {
317            write_top(x, dst)
318        }
319    }
320}
321
322/// Writes the decimal digits of `x`, not zero, at `dst`, without zeros in front, and returns how
323/// many: from 1 to 39. Above a limb, one division by `10^19` gives the last block, and the quotient,
324/// below `2^65`, is written as a limb, or for 39 digits as its top digit and a block.
325///
326/// # Safety
327///
328/// `dst` must be valid for writing as many bytes as `x` has digits.
329#[inline]
330unsafe fn write_u128(x: u128, dst: *mut u8) -> usize {
331    let (hi, lo) = ((x >> 64) as u64, x as u64);
332    // SAFETY: as the caller guarantees.
333    unsafe {
334        if hi == 0 {
335            return write_u64(lo, dst);
336        }
337        // The quotient `top B + q` and the last block `r`.
338        let (top, hi) = if hi >= TEN_19 {
339            (1, hi - TEN_19)
340        } else {
341            (0, hi)
342        };
343        let (q, r) = divide_2by1(hi, lo, TEN_19, TEN_19_INVERSE);
344        let n = if top == 0 {
345            write_u64(q, dst)
346        } else {
347            // `B + q`, from `1.8 10^19` to `3.7 10^19`: its first digit is 1, 2 or 3.
348            let y = (1 << 64) + u128::from(q);
349            let t = 1 + u64::from(y >= 2 * TEN_19 as u128) + u64::from(y >= 3 * TEN_19 as u128);
350            *dst = b'0' + t as u8;
351            write_block((y - u128::from(t) * u128::from(TEN_19)) as u64, dst.add(1));
352            20
353        };
354        write_block(r, dst.add(n));
355        n + 19
356    }
357}
358
359/// Writes the digits of the magnitude in the `n` limbs at `u`, least significant first, which it
360/// clobbers, in `radix`, not a power of two, at `dst`: exactly `width` digits, zeros in front,
361/// when given (enough for the magnitude), and otherwise without zeros in front, `0` for zero.
362/// Returns how many it wrote.
363///
364/// # Safety
365///
366/// `n < WRITE_SPLIT`; the `n + PASSES` limbs at `u` must be valid for reads and writes, and `dst`
367/// for writing the digits.
368unsafe fn write_limbs(
369    u: *mut u64,
370    n: usize,
371    radix: u32,
372    width: Option<usize>,
373    dst: *mut u8,
374) -> usize {
375    // A block takes more than 58 bits, as `b > 2^64 / 36`: at most two blocks a limb, and the
376    // groups of divisions may give up to `PASSES` blocks of zero above the top.
377    let mut blocks = [MaybeUninit::<u64>::uninit(); 2 * WRITE_SPLIT + PASSES];
378    let blocks = blocks.as_mut_ptr().cast::<u64>();
379    // SAFETY: as the caller guarantees.
380    unsafe {
381        let count = if radix == 10 {
382            decimal_blocks(u, n, blocks)
383        } else {
384            let (b, _) = block(radix);
385            let s = b.leading_zeros();
386            let base = Base {
387                s,
388                d: b << s,
389                v: reciprocal(b << s),
390            };
391            if SELECTS.contains(&radix) {
392                select_blocks(u, n, base, blocks)
393            } else {
394                other_blocks(u, n, base, blocks)
395            }
396        };
397        // The blocks below `count` are written.
398        put_blocks(
399            core::slice::from_raw_parts(blocks, count),
400            radix,
401            width,
402            dst,
403        )
404    }
405}
406
407/// The block `b` of a radix as its divisions take it: `b = d / 2^s` for the normalized `d`, whose
408/// reciprocal is `v`.
409#[derive(Clone, Copy)]
410struct Base {
411    s: u32,
412    d: u64,
413    v: u64,
414}
415
416/// [`divide_blocks`] by `10^19`, with the constants in the code.
417///
418/// # Safety
419///
420/// As for [`divide_blocks`].
421unsafe fn decimal_blocks(u: *mut u64, n: usize, blocks: *mut u64) -> usize {
422    let base = Base {
423        s: 0,
424        d: TEN_19,
425        v: TEN_19_INVERSE,
426    };
427    // SAFETY: as the caller guarantees.
428    unsafe { divide_blocks::<false>(u, n, base, blocks) }
429}
430
431/// [`divide_blocks`] by the block of another radix, with the second correction of a quotient a
432/// branch.
433///
434/// # Safety
435///
436/// As for [`divide_blocks`].
437unsafe fn other_blocks(u: *mut u64, n: usize, base: Base, blocks: *mut u64) -> usize {
438    // SAFETY: as the caller guarantees.
439    unsafe { divide_blocks::<false>(u, n, base, blocks) }
440}
441
442/// [`divide_blocks`] by the block of a radix in [`SELECTS`], with both corrections of a quotient
443/// selects.
444///
445/// # Safety
446///
447/// As for [`divide_blocks`].
448unsafe fn select_blocks(u: *mut u64, n: usize, base: Base, blocks: *mut u64) -> usize {
449    // SAFETY: as the caller guarantees.
450    unsafe { divide_blocks::<true>(u, n, base, blocks) }
451}
452
453/// The radices whose blocks, normalized, often need the second correction of the quotient
454/// estimated by the reciprocal: in a simulation of random steps, 6.6% of them for 6 and 36, 3.6%
455/// for 29, 2.8% for 34 and 1.5% for 26; 0.44% for 3 and 9, 0.007% for 10, and fewer for the
456/// others. Measured on an Apple M4 Max, selects made 512 bytes in radix 36 12% faster, and radices
457/// 3 and 7 10% slower, as they lengthen the chain of a division.
458const SELECTS: [u32; 5] = [6, 26, 29, 34, 36];
459
460/// Divides the magnitude in the `n` limbs at `u`, least significant first, which it clobbers, by
461/// the block `b` again and again until nothing is left, and writes the remainders at `blocks`,
462/// the least significant first; returns how many, without those of zero above the top, at least
463/// one.
464///
465/// The limbs of one division wait for each other: the remainder of a limb is the high limb of
466/// the next one's dividend, and a step, [`div_2by1`](divide_2by1), takes about ten cycles. But
467/// the next division needs only the quotient's limbs, from the top: so the divisions run in
468/// groups, in waves, each a limb behind the one before it, which hands it its quotient limbs in
469/// registers (see [`group`]). Their chains are independent, and the core runs them side by side.
470/// A group of `K` divisions takes `n + K - 1` waves, and leaves a number about `K` limbs shorter:
471/// the groups take as many divisions as the limbs left but one, rounded down to 1, 2, 4 or
472/// [`PASSES`], so that few blocks of zero come out above the top, and the last limb is divided
473/// alone.
474///
475/// # Safety
476///
477/// The `n + PASSES` limbs at `u` must be valid for reads and writes, and `blocks` for writing
478/// `2 n + PASSES` limbs.
479#[inline(always)]
480unsafe fn divide_blocks<const SELECT: bool>(
481    u: *mut u64,
482    mut n: usize,
483    base: Base,
484    blocks: *mut u64,
485) -> usize {
486    let mut count = 0;
487    // SAFETY: as the caller guarantees: a group of `K` takes `K` blocks of a number of more than
488    // `K` limbs, each more than 58 bits, so there are fewer than `2 n` blocks before the last
489    // group, which may write `PASSES - 1` zeros above them.
490    unsafe {
491        while n > 1 {
492            let out = blocks.add(count);
493            let (taken, left) = match n - 1 {
494                1 => (1, group::<1, SELECT>(u, n, base, out)),
495                2 | 3 => (2, group::<2, SELECT>(u, n, base, out)),
496                4..=7 => (4, group::<4, SELECT>(u, n, base, out)),
497                _ => (PASSES, group::<PASSES, SELECT>(u, n, base, out)),
498            };
499            count += taken;
500            n = left;
501        }
502        if n == 1 {
503            let (x, b) = (*u, base.d >> base.s);
504            *blocks.add(count) = x % b;
505            *blocks.add(count + 1) = x / b;
506            count += 2;
507        }
508        if count == 0 {
509            *blocks = 0;
510            count = 1;
511        }
512        while count > 1 && *blocks.add(count - 1) == 0 {
513            count -= 1;
514        }
515    }
516    count
517}
518
519/// One step of a division by the block `b`: the dividend `r B + x` for the remainder `r < b`
520/// carried as `r 2^s`, shifted by `s` bits to be divided by the normalized `d`; returns the
521/// quotient and the remainder, again as `r 2^s`.
522///
523/// With `SELECT`, both corrections of the quotient are selects; otherwise the second is a branch,
524/// as in [`div_2by1`](divide_2by1), which costs nothing while it is rare, and is a mispredicted
525/// branch and a call when it is not (see [`SELECTS`]).
526#[inline(always)]
527fn step<const SELECT: bool>(r: u64, x: u64, base: Base) -> (u64, u64) {
528    // `x >> (64 - s)` in two steps, so that `s = 0` shifts everything out.
529    let (u1, u0) = (r | ((x >> 1) >> (63 - base.s)), x << base.s);
530    if !SELECT {
531        return divide_2by1(u1, u0, base.d, base.v);
532    }
533    // Algorithm 4 of Möller and Granlund, as `div_2by1` computes it, with the second correction
534    // a select.
535    let (d, v) = (base.d, base.v);
536    let p = (u128::from(v) * u128::from(u1))
537        .wrapping_add((u128::from(u1.wrapping_add(1)) << 64) | u128::from(u0));
538    let (q, q0) = ((p >> 64) as u64, p as u64);
539    let r = u0.wrapping_sub(q.wrapping_mul(d));
540    let mask = u64::from(r > q0).wrapping_neg();
541    let (q, r) = (q.wrapping_add(mask), r.wrapping_add(mask & d));
542    let more = r >= d;
543    (
544        q + u64::from(more),
545        r - (d & u64::from(more).wrapping_neg()),
546    )
547}
548
549/// `K` divisions of the `n >= 2` limbs at `u` by the block `b`, one after another, in waves (see
550/// [`divide_blocks`]): writes the `K` remainders at `out`, the least significant first, leaves the
551/// quotient by `b^K` in the limbs at `u`, and returns its length.
552///
553/// In wave `t`, division `p` takes the limb at `n - 1 - (t - p)`: the first one reads it from `u`,
554/// the others take it from the one before, in the last wave, and the last one writes its quotient
555/// limb back. Above the top, the limbs are zero; below the bottom, a division is done, and its
556/// remainder is kept when it is.
557///
558/// # Safety
559///
560/// The `n + K` limbs at `u` must be valid for reads and writes, and the `K` at `out` for writes.
561#[inline(always)]
562unsafe fn group<const K: usize, const SELECT: bool>(
563    u: *mut u64,
564    n: usize,
565    base: Base,
566    out: *mut u64,
567) -> usize {
568    // The remainders, as `r 2^s`, and the quotient limb that each division hands the next one.
569    let mut r = [0u64; K];
570    let mut c = [0u64; K];
571    // SAFETY: the first division reads limbs `n - 1` down to 0; the last one writes limb
572    // `n - 1 + K - 1 - t` in wave `t`, from `n + K - 2` down to 0, after the first one read it,
573    // as `t` grows.
574    unsafe {
575        for t in 0..n {
576            let mut p = K;
577            while p > 1 {
578                p -= 1;
579                let (q, rest) = step::<SELECT>(r[p], c[p - 1], base);
580                r[p] = rest;
581                if p == K - 1 {
582                    *u.add(n + K - 2 - t) = q;
583                } else {
584                    c[p] = q;
585                }
586            }
587            let (q, rest) = step::<SELECT>(r[0], *u.add(n - 1 - t), base);
588            r[0] = rest;
589            if K == 1 {
590                *u.add(n - 1 - t) = q;
591            } else {
592                c[0] = q;
593            }
594        }
595        *out = r[0] >> base.s;
596        // The waves after the first division is done: in wave `n + i`, divisions `i + 1` up.
597        for i in 0..K - 1 {
598            let mut p = K;
599            while p > i + 1 {
600                p -= 1;
601                let (q, rest) = step::<SELECT>(r[p], c[p - 1], base);
602                r[p] = rest;
603                if p == K - 1 {
604                    *u.add(K - 2 - i) = q;
605                } else {
606                    c[p] = q;
607                }
608            }
609            *out.add(i + 1) = r[i + 1] >> base.s;
610        }
611    }
612    let mut len = n;
613    // SAFETY: the limbs below `len` are the quotient's.
614    while len > 0 && unsafe { *u.add(len - 1) } == 0 {
615        len -= 1;
616    }
617    len
618}
619
620/// Writes the blocks, the least significant first, of `k` digits each in `radix`, as digits at
621/// `dst`: exactly `width` digits when given, zeros in front, and otherwise without zeros in front,
622/// `0` for zero. Returns how many.
623///
624/// # Safety
625///
626/// `blocks` must not be empty, and `dst` valid for writing the digits; `width`, when given, must
627/// have room for the digits of the blocks but their zeros in front.
628unsafe fn put_blocks(blocks: &[u64], radix: u32, width: Option<usize>, dst: *mut u8) -> usize {
629    let (_, k) = block(radix);
630    let count = blocks.len();
631    // SAFETY: as the caller guarantees.
632    unsafe {
633        // The digits in all, and the blocks written whole, from the least significant; the
634        // digits above them first.
635        let (total, whole) = match width {
636            None => {
637                let top = blocks[count - 1];
638                let head = if radix == 10 {
639                    write_top(top, dst)
640                } else {
641                    write_short_top(top, Radix::new(radix), dst)
642                };
643                (head + k * (count - 1), count - 1)
644            }
645            Some(w) => {
646                // The blocks that fit whole; above them the low digits of the next one, or zeros.
647                let whole = (w / k).min(count);
648                let head = w - k * whole;
649                if head > 0 {
650                    let next = if whole < count { blocks[whole] } else { 0 };
651                    write_partial(next, radix, k, head, dst);
652                }
653                (w, whole)
654            }
655        };
656        let mut at = dst.add(total);
657        if radix == 10 {
658            for &b in &blocks[..whole] {
659                at = at.sub(k);
660                write_block(b, at);
661            }
662        } else {
663            // Four blocks at once: the digits of a block wait for each other, a division each,
664            // and the four chains run side by side.
665            let radix = Radix::new(radix);
666            let (fours, rest) = blocks[..whole].as_chunks::<4>();
667            for four in fours {
668                at = at.sub(4 * k);
669                write_four(*four, radix, at, k);
670            }
671            for &b in rest {
672                at = at.sub(k);
673                write_digits(b, radix, at, k);
674            }
675        }
676        total
677    }
678}
679
680/// Writes the `n` low digits of `x` in `radix`, zeros in front, at `dst`: a block cut short, or
681/// zeros alone for `x` of zero.
682///
683/// # Safety
684///
685/// `dst` must be valid for writing `n` bytes; `x` must have at most `n` digits.
686unsafe fn write_partial(x: u64, radix: u32, k: usize, n: usize, dst: *mut u8) {
687    // SAFETY: as the caller guarantees.
688    unsafe {
689        if n <= k {
690            let mut buffer = [0u8; 64];
691            if radix == 10 {
692                write_block(x, buffer.as_mut_ptr());
693            } else {
694                write_digits(x, Radix::new(radix), buffer.as_mut_ptr(), k);
695            }
696            core::ptr::copy_nonoverlapping(buffer.as_ptr().add(k - n), dst, n);
697        } else {
698            core::ptr::write_bytes(dst, b'0', n - k);
699            write_partial(x, radix, k, k, dst.add(n - k));
700        }
701    }
702}
703
704/// Writes `x` in `radix` into the `n` bytes at `dst`, the most significant digit first, with zeros
705/// in front: `x` must have at most `n` digits.
706///
707/// # Safety
708///
709/// `dst` must be valid for writing `n` bytes.
710unsafe fn write_digits(mut x: u64, radix: Radix, dst: *mut u8, n: usize) {
711    // SAFETY: as the caller guarantees.
712    unsafe {
713        for i in (0..n).rev() {
714            let (q, digit) = radix.div_rem(x);
715            *dst.add(i) = DIGITS[digit as usize];
716            x = q;
717        }
718    }
719}
720
721/// Writes the blocks `x`, the least significant first, of `n` digits each in `radix`, into the
722/// `4 n` bytes at `dst`, the most significant digit first: the four chains of divisions in one
723/// loop.
724///
725/// # Safety
726///
727/// `dst` must be valid for writing `4 n` bytes; each block must have at most `n` digits.
728unsafe fn write_four(mut x: [u64; 4], radix: Radix, dst: *mut u8, n: usize) {
729    // SAFETY: block `j` goes to the `n` bytes at `dst + (3 - j) n`.
730    unsafe {
731        for i in (0..n).rev() {
732            for (j, x) in x.iter_mut().enumerate() {
733                let (q, digit) = radix.div_rem(*x);
734                *dst.add((3 - j) * n + i) = DIGITS[digit as usize];
735                *x = q;
736            }
737        }
738    }
739}
740
741/// Writes the digits of the top block `x` in `radix`, not 10, at `dst`, without zeros in front, `0`
742/// for zero; returns how many.
743///
744/// # Safety
745///
746/// `dst` must be valid for writing the digits.
747unsafe fn write_short_top(mut x: u64, radix: Radix, dst: *mut u8) -> usize {
748    let mut buffer = [0u8; 64];
749    let mut i = 64;
750    loop {
751        i -= 1;
752        let (q, digit) = radix.div_rem(x);
753        buffer[i] = DIGITS[digit as usize];
754        x = q;
755        if x == 0 {
756            break;
757        }
758    }
759    // SAFETY: as the caller guarantees.
760    unsafe { core::ptr::copy_nonoverlapping(buffer.as_ptr().add(i), dst, 64 - i) };
761    64 - i
762}
763
764/// A radix from 3 to 36 to divide by with a multiplication, as Granlund and Montgomery divide by
765/// an invariant integer: exact for every `u64`. The hardware's division takes about 10 cycles and
766/// does not overlap with the next one, which made the digits of radices other than 10 the larger
767/// part of writing them: on an Apple M4 Max, 512 bytes in radix 36 took 16,700 cycles with it.
768#[derive(Clone, Copy)]
769struct Radix {
770    /// The radix.
771    d: u64,
772    /// `floor(2^64 (2^l - d) / d) + 1`, below `2^64` as `2^l - d < d`.
773    m: u64,
774    /// `ceil(log2 d)`, at least 2.
775    l: u32,
776}
777
778impl Radix {
779    /// The radix `d`, from 3 to 36, prepared.
780    fn new(d: u32) -> Radix {
781        let d = u64::from(d);
782        let l = 64 - (d - 1).leading_zeros();
783        let m = (((1u128 << l) - u128::from(d)) << 64) / u128::from(d) + 1;
784        Radix { d, m: m as u64, l }
785    }
786
787    /// The quotient and the remainder of `n` by the radix.
788    #[inline(always)]
789    fn div_rem(self, n: u64) -> (u64, u64) {
790        // `t <= n`, as `m < 2^64`; the halved difference does not overflow.
791        let t = ((u128::from(self.m) * u128::from(n)) >> 64) as u64;
792        let q = (t + ((n - t) >> 1)) >> (self.l - 1);
793        (q, n - q * self.d)
794    }
795}
796
797// Decimal digits in lanes
798
799/// The eight decimal digits of `x < 10^8` as values from 0 to 9, the most significant in the
800/// lowest byte: split in halves of four digits in the 32-bit lanes, each in pairs in the 16-bit
801/// lanes, each in digits in the bytes, by multiplications that divide by 10^4, 100 and 10 in all
802/// lanes at once (`x · m >> k` with `m` the reciprocal rounded up: exact for these ranges).
803#[inline(always)]
804fn eight_digits(x: u64) -> u64 {
805    // x / 10^4 for x < 4.9 10^8.
806    let hi = (x * 109_951_163) >> 40;
807    let x = hi | ((x - hi * 10_000) << 32);
808    // Lanes / 100, for lanes below 43,690.
809    let q = ((x * 10_486) >> 20) & 0x0000_007F_0000_007F;
810    let x = q | ((x - q * 100) << 16);
811    // Lanes / 10, for lanes below 170.
812    let t = ((x * 103) >> 10) & 0x000F_000F_000F_000F;
813    t | ((x - t * 10) << 8)
814}
815
816/// Writes the 19 decimal digits of the block `x < 10^19` at `dst`, zeros in front.
817///
818/// # Safety
819///
820/// `dst` must be valid for writing 19 bytes.
821#[inline(always)]
822unsafe fn write_block(x: u64, dst: *mut u8) {
823    let (a, b, c) = split_block(x);
824    let zeros = 0x3030_3030_3030_3030;
825    // SAFETY: the writes lie in the 19 bytes: `[0, 4)`, then `[3, 11)` over its last byte, and
826    // `[11, 19)`.
827    unsafe {
828        write(dst, (three_digits(a) as u32 | 0x0030_3030).to_le_bytes());
829        write(dst.add(3), (eight_digits(b) | zeros).to_le_bytes());
830        write(dst.add(11), (eight_digits(c) | zeros).to_le_bytes());
831    }
832}
833
834/// The block `x < 10^19` as its top three digits, `x / 10^16`, and two groups of eight.
835#[inline(always)]
836fn split_block(x: u64) -> (u64, u64, u64) {
837    let a = x / 10_000_000_000_000_000;
838    let rest = x - a * 10_000_000_000_000_000;
839    let b = rest / 100_000_000;
840    (a, b, rest - b * 100_000_000)
841}
842
843/// The three decimal digits of `x < 1000` as values, the most significant in the lowest byte.
844#[inline(always)]
845fn three_digits(x: u64) -> u64 {
846    // x / 100 for x < 1024, then the two below.
847    let h = (x * 41) >> 12;
848    let rest = x - h * 100;
849    let t = (rest * 103) >> 10;
850    h | (t << 8) | ((rest - t * 10) << 16)
851}
852
853/// Writes the decimal digits of the block `x < 10^19` at `dst`, without zeros in front, `0` for
854/// zero; returns how many, from 1 to 19. The digits are made in a buffer, and only they are
855/// copied.
856///
857/// # Safety
858///
859/// `dst` must be valid for writing as many bytes as `x` has digits.
860#[inline(always)]
861unsafe fn write_top(x: u64, dst: *mut u8) -> usize {
862    let (a, b, c) = split_block(x);
863    let (a, b, c) = (three_digits(a), eight_digits(b), eight_digits(c));
864    // The zeros in front: the zero bytes at the bottom of the first group with a digit that is
865    // not zero, the most significant in the lowest byte.
866    let zeros = if a != 0 {
867        a.trailing_zeros() / 8
868    } else if b != 0 {
869        3 + b.trailing_zeros() / 8
870    } else {
871        11 + (c | 1 << 56).trailing_zeros() / 8
872    } as usize;
873    let mut buffer = [0u8; 24];
874    let ascii = 0x3030_3030_3030_3030;
875    let p = buffer.as_mut_ptr();
876    // SAFETY: the buffer holds the digits at `[5, 24)`, and `dst` has room for the `19 - zeros`
877    // copied.
878    unsafe {
879        write(p.add(4), ((a << 8) as u32 | 0x3030_3030).to_le_bytes());
880        write(p.add(8), (b | ascii).to_le_bytes());
881        write(p.add(16), (c | ascii).to_le_bytes());
882        copy_short(dst, p.add(5 + zeros), 19 - zeros);
883    }
884    19 - zeros
885}
886
887/// Copies the `n` bytes at `src`, from 1 to 24, to `dst`, apart from them: in up to three copies
888/// of eight, four or one, which overlap where `n` is not a multiple, and agree there.
889///
890/// # Safety
891///
892/// The bytes must be valid for reads at `src` and for writes at `dst`.
893#[inline(always)]
894unsafe fn copy_short(dst: *mut u8, src: *const u8, n: usize) {
895    // SAFETY: every access lies in the `n` bytes.
896    unsafe {
897        if n >= 8 {
898            write::<8>(dst, read(src));
899            if n > 16 {
900                write::<8>(dst.add(8), read(src.add(8)));
901            }
902            write::<8>(dst.add(n - 8), read(src.add(n - 8)));
903        } else if n >= 4 {
904            write::<4>(dst, read(src));
905            write::<4>(dst.add(n - 4), read(src.add(n - 4)));
906        } else {
907            *dst = *src;
908            *dst.add(n / 2) = *src.add(n / 2);
909            *dst.add(n - 1) = *src.add(n - 1);
910        }
911    }
912}
913
914// Divide and conquer
915
916/// A power `b^(2^i)` of the block for divide and conquer, without its zero bytes at the bottom.
917struct Power {
918    /// The power divided by `256^zeros`, little-endian, in the shortest form.
919    odd: Number,
920    /// The zero bytes at the bottom of the power.
921    zeros: usize,
922    /// Its places: `k 2^i` digits.
923    places: usize,
924    /// [`Power::odd`] prepared for dividing by it, when it first is.
925    divisor: Option<Divisor>,
926}
927
928impl Power {
929    /// The length of the power in bytes.
930    fn bytes(&self) -> usize {
931        self.odd.value.len() + self.zeros
932    }
933
934    /// The first power, `b`, of `k` places.
935    fn first(b: u64, k: usize) -> Power {
936        let zeros = (b.trailing_zeros() / 8) as usize;
937        Power {
938            odd: Number::new(
939                (b >> (8 * zeros)).to_le_bytes().to_vec(),
940                ByteOrder::LittleEndian,
941            ),
942            zeros,
943            places: k,
944            divisor: None,
945        }
946    }
947
948    /// The square of this power.
949    fn square(&self) -> Power {
950        let mut odd = &self.odd * &self.odd;
951        let more = odd.value.iter().take_while(|&&byte| byte == 0).count();
952        odd.value.drain(..more);
953        Power {
954            odd,
955            zeros: 2 * self.zeros + more,
956            places: 2 * self.places,
957            divisor: None,
958        }
959    }
960}
961
962/// The index of the largest power in `powers`, computed as they are first needed from `b` of `k`
963/// places, for which `fits(bytes, places)` holds, or 0. A square has at least twice the bytes of
964/// its root but one, and is computed only when that many may fit.
965fn largest(
966    powers: &mut Vec<Power>,
967    b: u64,
968    k: usize,
969    fits: impl Fn(usize, usize) -> bool,
970) -> usize {
971    if powers.is_empty() {
972        powers.push(Power::first(b, k));
973    }
974    let mut i = 0;
975    loop {
976        if i + 1 == powers.len() {
977            let p = &powers[i];
978            if !fits(2 * p.bytes() - 1, 2 * p.places) {
979                return i;
980            }
981            let next = p.square();
982            powers.push(next);
983        }
984        let p = &powers[i + 1];
985        if !fits(p.bytes(), p.places) {
986            return i;
987        }
988        i += 1;
989    }
990}
991
992/// Writes the digits of the magnitude `x`, little-endian in the shortest form, in `radix` at
993/// `dst`, as [`write_limbs`] writes them, and returns how many: by divide and conquer, divided by
994/// the largest power `b^(2^i)` that has at most half its limbs and one, the quotient written
995/// first, then the remainder in `k 2^i` places.
996///
997/// The power is `odd 256^zeros`; only the bytes of `x` from `zeros` up are divided by `odd`,
998/// and the remainder's are put above the bytes below them. `top` is set for the first split, whose
999/// power divides nothing else.
1000///
1001/// # Safety
1002///
1003/// `dst` must be valid for writing the digits.
1004unsafe fn write_split(
1005    x: Number,
1006    radix: u32,
1007    width: Option<usize>,
1008    dst: *mut u8,
1009    powers: &mut Vec<Power>,
1010    top: bool,
1011) -> usize {
1012    let limbs = x.value.len().div_ceil(8);
1013    // SAFETY: as the caller guarantees.
1014    unsafe {
1015        if limbs < WRITE_SPLIT {
1016            if limbs == 0 || x.value == [0] {
1017                return write_limbs([0; PASSES + 1].as_mut_ptr(), 0, radix, width, dst);
1018            }
1019            let mut u = [MaybeUninit::<u64>::uninit(); WRITE_SPLIT + PASSES];
1020            let u = u.as_mut_ptr().cast::<u64>();
1021            to_limbs(Operand::of(&x), u);
1022            return write_limbs(u, limbs, radix, width, dst);
1023        }
1024        let (b, k) = block(radix);
1025        let half = 8 * (limbs.div_ceil(2) + 1);
1026        let i = largest(powers, b, k, |bytes, _| bytes <= half);
1027        let power = &mut powers[i];
1028        let (zeros, places) = (power.zeros, power.places);
1029        let (q, r) = if x.value.len() > zeros {
1030            let high = Number {
1031                value: x.value[zeros..].to_vec(),
1032                negative: false,
1033                byte_order: ByteOrder::LittleEndian,
1034            };
1035            // The largest power divides once, at the top; the others divide the parts below it,
1036            // each at least twice, and are prepared as divisors, which keep the inverse of
1037            // Newton's method from one division to the next.
1038            let (q, r) = if top {
1039                high.div_rem(&power.odd)
1040            } else {
1041                power
1042                    .divisor
1043                    .get_or_insert_with(|| Divisor::new(&power.odd))
1044                    .div_rem(&high)
1045            };
1046            let mut low = x.value;
1047            low.truncate(zeros);
1048            if r.value != [0] {
1049                low.extend_from_slice(&r.value);
1050            }
1051            (q, trimmed(low))
1052        } else {
1053            (Number::new(vec![0], ByteOrder::LittleEndian), x)
1054        };
1055        let n = match width {
1056            // Without a quotient, the remainder is the number, and has no zeros in front.
1057            None if q.value == [0] => return write_split(r, radix, None, dst, powers, top),
1058            None => write_split(q, radix, None, dst, powers, false),
1059            Some(w) => write_split(q, radix, Some(w - places), dst, powers, false),
1060        };
1061        n + write_split(r, radix, Some(places), dst.add(n), powers, false)
1062    }
1063}
1064
1065/// `value` as a little-endian number in the shortest form.
1066fn trimmed(mut value: Vec<u8>) -> Number {
1067    while value.len() > 1 && value.last() == Some(&0) {
1068        value.pop();
1069    }
1070    if value.is_empty() {
1071        value.push(0);
1072    }
1073    Number {
1074        value,
1075        negative: false,
1076        byte_order: ByteOrder::LittleEndian,
1077    }
1078}
1079
1080// Radices that are powers of two
1081
1082/// Writes the digits of the magnitude of the operand `x`, not zero, in the radix `2^bits` at
1083/// `dst`, without zeros in front, and returns how many: read where they are, from the most
1084/// significant byte. Hexadecimal is two digits a byte, from a table, binary eight, spread over the
1085/// bytes of a `u64` by one multiplication; other radices take groups of `bits` bits from the low
1086/// end, written from the back.
1087///
1088/// # Safety
1089///
1090/// The operand's vector must be valid for reads, and `dst` for writing the digits.
1091unsafe fn write_bits(x: Operand, bits: u32, dst: *mut u8) -> usize {
1092    // SAFETY: as the caller guarantees.
1093    let bytes = unsafe { significant(x) };
1094    let l = bytes.len();
1095    // Byte `i` of the magnitude from the most significant.
1096    // SAFETY: `i < l`.
1097    let from_top =
1098        |i: usize| unsafe { *bytes.get_unchecked(if x.big_endian { i } else { l - 1 - i }) };
1099    let top = from_top(0);
1100    // The digits, counted in 64 bits: their number fits, as the caller has room for them.
1101    let total = 8 * (l as u64 - 1) + u64::from(8 - top.leading_zeros());
1102    let n = total.div_ceil(u64::from(bits)) as usize;
1103    // SAFETY: as the caller guarantees, `dst` has room for the `n` digits; the top byte's digits
1104    // come first, then those of each byte below it.
1105    unsafe {
1106        match bits {
1107            4 => {
1108                let mut at = dst;
1109                if top < 16 {
1110                    *at = DIGITS[usize::from(top)];
1111                    at = at.add(1);
1112                } else {
1113                    write(at, HEX[usize::from(top)]);
1114                    at = at.add(2);
1115                }
1116                for i in 1..l {
1117                    write(at, HEX[usize::from(from_top(i))]);
1118                    at = at.add(2);
1119                }
1120            }
1121            1 => {
1122                let k = 8 - top.leading_zeros() as usize;
1123                for j in 0..k {
1124                    *dst.add(j) = b'0' + ((top >> (k - 1 - j)) & 1);
1125                }
1126                for i in 1..l {
1127                    write(dst.add(k + 8 * (i - 1)), binary_digits(from_top(i)));
1128                }
1129            }
1130            _ => {
1131                // Whole groups of bytes from the bottom, then the digits above them one by one.
1132                let (mut next, mut j) = match bits {
1133                    2 => groups::<2, 1, 4>(from_top, l, n, dst),
1134                    3 => groups::<3, 3, 8>(from_top, l, n, dst),
1135                    _ => groups::<5, 5, 8>(from_top, l, n, dst),
1136                };
1137                let mask = (1u32 << bits) - 1;
1138                let (mut acc, mut have) = (0u32, 0u32);
1139                while j > 0 {
1140                    j -= 1;
1141                    if have < bits && next > 0 {
1142                        next -= 1;
1143                        acc |= u32::from(from_top(next)) << have;
1144                        have += 8;
1145                    }
1146                    *dst.add(j) = DIGITS[(acc & mask) as usize];
1147                    acc >>= bits;
1148                    have = have.saturating_sub(bits);
1149                }
1150            }
1151        }
1152    }
1153    n
1154}
1155
1156/// Writes the digits of the magnitude of `l` bytes, `from_top(i)` its byte `i` from the most
1157/// significant, of `n` digits in the radix `2^B`, from the bottom in groups of `G` bytes, `D`
1158/// digits each, the last of the `n` digits at `dst` first; returns the bytes and the digits above
1159/// the groups, left to write.
1160///
1161/// # Safety
1162///
1163/// `dst` must be valid for writing `n` bytes.
1164#[inline(always)]
1165unsafe fn groups<const B: u32, const G: usize, const D: usize>(
1166    from_top: impl Fn(usize) -> u8,
1167    l: usize,
1168    n: usize,
1169    dst: *mut u8,
1170) -> (usize, usize) {
1171    let (mut bytes, mut digits) = (l, n);
1172    while bytes >= G && digits >= D {
1173        let mut v = 0u64;
1174        for t in 0..G {
1175            v |= u64::from(from_top(bytes - 1 - t)) << (8 * t);
1176        }
1177        for t in 0..D {
1178            // SAFETY: `digits - 1 - t < n`.
1179            unsafe {
1180                *dst.add(digits - 1 - t) =
1181                    DIGITS[((v >> (B as usize * t)) & ((1 << B) - 1)) as usize]
1182            };
1183        }
1184        bytes -= G;
1185        digits -= D;
1186    }
1187    (bytes, digits)
1188}
1189
1190/// The eight binary digits of `byte` as ASCII, the most significant first: bit `7 - i` moved to
1191/// byte `i` by a multiplication that adds copies of `byte` nine bits apart, which cannot overlap.
1192#[inline(always)]
1193fn binary_digits(byte: u8) -> [u8; 8] {
1194    let spread = (u64::from(byte).wrapping_mul(0x8040_2010_0804_0201) >> 7) & 0x0101_0101_0101_0101;
1195    (spread | 0x3030_3030_3030_3030).to_le_bytes()
1196}
1197
1198/// The two hexadecimal digits of each byte.
1199const HEX: [[u8; 2]; 256] = {
1200    let mut t = [[0; 2]; 256];
1201    let mut i = 0;
1202    while i < 256 {
1203        t[i] = [DIGITS[i >> 4], DIGITS[i & 15]];
1204        i += 1;
1205    }
1206    t
1207};
1208
1209/// The value of each character as a digit, 36 or more when it is none.
1210const VALUES: [u8; 256] = {
1211    let mut t = [255; 256];
1212    let mut i = 0;
1213    while i < 36 {
1214        t[DIGITS[i] as usize] = i as u8;
1215        t[DIGITS[i].to_ascii_uppercase() as usize] = i as u8;
1216        i += 1;
1217    }
1218    t
1219};
1220
1221/// The number of the digits `text` in the radix `2^bits`, the most significant first, in
1222/// `order`, `negative` if not zero; `None` when a character is not a digit. One pass from the
1223/// last digit, each byte written in its place in `order`: two digits a byte for hexadecimal, and
1224/// otherwise the digits' bits gathered in a register; the digits' values are or-ed together, and
1225/// the radix checked once.
1226fn read_bits(text: &[u8], bits: u32, negative: bool, order: ByteOrder) -> Option<Number> {
1227    // Zeros in front count for nothing.
1228    let start = text.iter().position(|&c| c != b'0').unwrap_or(text.len());
1229    let digits = &text[start..];
1230    let Some(&first) = digits.first() else {
1231        return Some(zero(order));
1232    };
1233    let top = VALUES[usize::from(first)];
1234    if top >> bits != 0 {
1235        return None;
1236    }
1237    let n = digits.len();
1238    // Counted in 64 bits; the bytes are fewer than the digits, so their number fits.
1239    let len = (u64::from(bits) * (n as u64 - 1) + u64::from(8 - top.leading_zeros())).div_ceil(8)
1240        as usize;
1241    let mut value = Vec::<u8>::with_capacity(len);
1242    let be = order == ByteOrder::BigEndian;
1243    let out = value.as_mut_ptr();
1244    let mut seen = 0u8;
1245    // SAFETY: the bytes written are `len`, each at its own place below `len`: the significant
1246    // bits are `len` bytes, and no digit's bits go above them, as the top digit's are counted.
1247    unsafe {
1248        let put = |j: usize, byte: u8| *out.add(if be { len - 1 - j } else { j }) = byte;
1249        let digit = |i: usize| VALUES[usize::from(*digits.get_unchecked(i))];
1250        if bits == 4 {
1251            // Hexadecimal: a byte from two digits, `ceil(n / 2)` of them, as the top digit is not
1252            // zero.
1253            let mut j = 0;
1254            let mut i = n;
1255            while i >= 2 {
1256                let (high, low) = (digit(i - 2), digit(i - 1));
1257                seen |= high | low;
1258                put(j, high << 4 | low);
1259                j += 1;
1260                i -= 2;
1261            }
1262            if i == 1 {
1263                put(j, top);
1264            }
1265        } else {
1266            let (mut acc, mut have, mut j) = (0u32, 0u32, 0);
1267            for i in (0..n).rev() {
1268                let v = digit(i);
1269                seen |= v;
1270                acc |= u32::from(v) << have;
1271                have += bits;
1272                if have >= 8 {
1273                    put(j, acc as u8);
1274                    j += 1;
1275                    acc >>= 8;
1276                    have -= 8;
1277                }
1278            }
1279            if j < len {
1280                put(j, acc as u8);
1281            }
1282        }
1283        if seen >> bits != 0 {
1284            return None;
1285        }
1286        value.set_len(len);
1287    }
1288    Some(Number {
1289        value,
1290        negative,
1291        byte_order: order,
1292    })
1293}
1294
1295/// Zero, `[0]`, in `order`.
1296fn zero(order: ByteOrder) -> Number {
1297    Number {
1298        value: vec![0],
1299        negative: false,
1300        byte_order: order,
1301    }
1302}
1303
1304// Reading decimal text
1305
1306/// Eight ASCII zeros.
1307const ASCII_ZEROS: u64 = 0x3030_3030_3030_3030;
1308
1309/// Not zero when a byte of `w` is not an ASCII digit: the high half of each byte must be 3, and
1310/// stay 3 when 6 is added. A carry from adding 6 to one byte into the next comes only from a byte
1311/// of 0xFA or more, which fails anyway.
1312#[inline(always)]
1313fn not_digits(w: u64) -> u64 {
1314    let high = 0xF0F0_F0F0_F0F0_F0F0;
1315    ((w & high) | ((w.wrapping_add(0x0606_0606_0606_0606) & high) >> 4)) ^ 0x3333_3333_3333_3333
1316}
1317
1318/// The value of the eight ASCII digits of `w`, the most significant in the lowest byte: pairs in
1319/// the bytes, `10 x[i] + x[i + 1]`, then the pairs weighted by multiplications whose high halves
1320/// sum them. Wrapping on bytes that are not digits, whose value does not matter.
1321#[inline(always)]
1322fn eight_value(w: u64) -> u64 {
1323    let x = w.wrapping_sub(ASCII_ZEROS);
1324    let x = x.wrapping_mul(10).wrapping_add(x >> 8);
1325    let pairs = 0x0000_00FF_0000_00FF;
1326    (x & pairs)
1327        .wrapping_mul(100 + (1_000_000 << 32))
1328        .wrapping_add(((x >> 16) & pairs).wrapping_mul(1 + (10_000 << 32)))
1329        >> 32
1330}
1331
1332/// The value of the 19 ASCII digits at `p` and whether one is not a digit (not zero then).
1333///
1334/// # Safety
1335///
1336/// The 19 bytes must be valid for reads.
1337#[inline(always)]
1338unsafe fn block_value(p: *const u8) -> (u64, u64) {
1339    // SAFETY: as the caller guarantees: `[0, 8)`, `[8, 16)` and `[11, 19)`.
1340    let (a, b, c) = unsafe {
1341        (
1342            u64::from_le_bytes(read(p)),
1343            u64::from_le_bytes(read(p.add(8))),
1344            u64::from_le_bytes(read(p.add(11))),
1345        )
1346    };
1347    // The last three digits: those of `[11, 19)` with the five that `b` has made zeros.
1348    let low = (c & 0xFFFF_FF00_0000_0000) | 0x0000_0030_3030_3030;
1349    let value = eight_value(a)
1350        .wrapping_mul(100_000_000_000)
1351        .wrapping_add(eight_value(b).wrapping_mul(1000))
1352        .wrapping_add(eight_value(low));
1353    (value, not_digits(a) | not_digits(b) | not_digits(c))
1354}
1355
1356/// The value of the `n` ASCII digits at `p`, from 1 to 19, and whether one is not a digit: copied
1357/// behind zeros to make 19.
1358///
1359/// # Safety
1360///
1361/// The `n` bytes must be valid for reads.
1362#[inline(always)]
1363unsafe fn head_value(p: *const u8, n: usize) -> (u64, u64) {
1364    let mut buffer = [b'0'; 24];
1365    // SAFETY: the buffer holds the 19 digits from 5 up, the last `n` copied.
1366    unsafe {
1367        copy_short(buffer.as_mut_ptr().add(24 - n), p, n);
1368        block_value(buffer.as_ptr().add(5))
1369    }
1370}
1371
1372/// The number of the decimal digits `text`, `negative` if not zero, in `order`; `None` when a
1373/// character is not a digit. Up to 38 digits in registers, up to [`READ_SPLIT`] blocks in limbs.
1374fn read_decimal(text: &[u8], negative: bool, order: ByteOrder) -> Option<Number> {
1375    let n = text.len();
1376    if n <= 38 {
1377        let p = text.as_ptr();
1378        let head = n - 19 * ((n - 1) / 19);
1379        // SAFETY: the reads lie in the text: the head's `head` bytes, then 19 for 20 digits up.
1380        let (x, bad) = unsafe {
1381            let (first, bad) = head_value(p, head);
1382            if n <= 19 {
1383                (u128::from(first), bad)
1384            } else {
1385                let (low, more) = block_value(p.add(head));
1386                (
1387                    u128::from(first) * u128::from(TEN_19) + u128::from(low),
1388                    bad | more,
1389                )
1390            }
1391        };
1392        return (bad == 0).then(|| small_number(x, negative, order));
1393    }
1394    read_long(text, 10, negative, order)
1395}
1396
1397/// The number of the digits `text` in `radix`, not a power of two, `negative` if not zero, in
1398/// `order`; `None` when a character is not a digit. Up to [`READ_SPLIT`] blocks in limbs, on the
1399/// stack for up to [`STACK_BLOCKS`], and by divide and conquer beyond.
1400fn read_long(text: &[u8], radix: u32, negative: bool, order: ByteOrder) -> Option<Number> {
1401    let (b, k) = block(radix);
1402    let blocks = text.len().div_ceil(k);
1403    if blocks <= READ_SPLIT {
1404        let mut stack = [MaybeUninit::<u64>::uninit(); STACK_BLOCKS + 1];
1405        let mut heap = Vec::new();
1406        let x = if blocks <= STACK_BLOCKS {
1407            stack.as_mut_ptr().cast::<u64>()
1408        } else {
1409            heap.reserve_exact(blocks + 1);
1410            heap.as_mut_ptr()
1411        };
1412        // SAFETY: the limbs have room for one a block and one more.
1413        let len = unsafe { read_blocks(text, radix, b, k, x)? };
1414        return Some(limbs_number(x, len, negative, order));
1415    }
1416    let mut powers = Vec::new();
1417    let x = read_split(text, radix, &mut powers)?;
1418    Some(in_order(x, negative, order))
1419}
1420
1421/// Sets the `len` limbs at `x` to `x b + v`, and returns the limb that carries out of them.
1422///
1423/// # Safety
1424///
1425/// The limbs must be valid for reads and writes.
1426#[inline(always)]
1427unsafe fn mul_add(x: *mut u64, len: usize, b: u64, v: u64) -> u64 {
1428    let mut carry = v;
1429    // SAFETY: as the caller guarantees.
1430    unsafe {
1431        for i in 0..len {
1432            let t = u128::from(*x.add(i)) * u128::from(b) + u128::from(carry);
1433            *x.add(i) = t as u64;
1434            carry = (t >> 64) as u64;
1435        }
1436    }
1437    carry
1438}
1439
1440/// The magnitude `x` as a number with the sign `negative`, in `order`, in one new vector of
1441/// exactly its length.
1442fn small_number(x: u128, negative: bool, order: ByteOrder) -> Number {
1443    let limbs = [x as u64, (x >> 64) as u64];
1444    let len = usize::from(x != 0) + usize::from(x >> 64 != 0);
1445    // SAFETY: the limbs hold the `len` limbs.
1446    limbs_number(limbs.as_ptr().cast_mut(), len, negative, order)
1447}
1448
1449/// The `len` limbs at `x`, least significant first, as a number with the sign `negative`, in
1450/// `order`, in the shortest form, in one new vector of exactly its length.
1451fn limbs_number(x: *mut u64, len: usize, negative: bool, order: ByteOrder) -> Number {
1452    // SAFETY: the caller hands over `len` limbs; the top one is not zero.
1453    let bytes = if len == 0 {
1454        1
1455    } else {
1456        8 * len - unsafe { *x.add(len - 1) }.leading_zeros() as usize / 8
1457    };
1458    let p = Product {
1459        r: if len == 0 { core::ptr::null() } else { x },
1460        len: bytes,
1461        negative: negative && len != 0,
1462    };
1463    let mut value = Vec::with_capacity(bytes);
1464    // SAFETY: the vector has room for the bytes, all of which are written before the length is
1465    // set.
1466    unsafe {
1467        p.write(value.as_mut_ptr(), order);
1468        value.set_len(bytes);
1469    }
1470    Number {
1471        value,
1472        negative: p.negative,
1473        byte_order: order,
1474    }
1475}
1476
1477/// `x`, little-endian in the shortest form, as a number with the sign `negative` in `order`.
1478fn in_order(mut x: Number, negative: bool, order: ByteOrder) -> Number {
1479    if order == ByteOrder::BigEndian {
1480        x.value.reverse();
1481    }
1482    x.negative = negative && x.value != [0];
1483    x.byte_order = order;
1484    x
1485}
1486
1487// Blocks of digits
1488
1489/// Reads the digits `text` in `radix`, not a power of two, in blocks of `k` of `b = radix^k`,
1490/// the first one shorter when the digits do not fill it, into the limbs `x`, least significant
1491/// first; returns how many it holds, or `None` when a character is not a digit. Decimal blocks are
1492/// read eight digits at a time, other ones a digit at a time; they are multiplied in
1493/// [`READ_PASSES`] at a time, once the number has [`READ_WAVES`] limbs.
1494///
1495/// # Safety
1496///
1497/// `x` must be valid for writing one limb a block and one more; only the limbs written are read.
1498unsafe fn read_blocks(text: &[u8], radix: u32, b: u64, k: usize, x: *mut u64) -> Option<usize> {
1499    let n = text.len();
1500    let head = n - k * ((n - 1) / k);
1501    let count = (n - head) / k;
1502    let p = text.as_ptr();
1503    let mut bad = 0u64;
1504    // The value of the `k` digits at `at`, which turns `bad` not zero when one is not a digit.
1505    let mut value = |at: usize, len: usize| -> u64 {
1506        if radix == 10 {
1507            // SAFETY: the `len` bytes at `at` lie in the text, 19 of them for a whole block.
1508            let (v, more) = unsafe {
1509                if len == 19 {
1510                    block_value(p.add(at))
1511                } else {
1512                    head_value(p.add(at), len)
1513                }
1514            };
1515            bad |= more;
1516            v
1517        } else {
1518            text[at..at + len].iter().fold(0u64, |acc, &c| {
1519                let v = VALUES[usize::from(c)];
1520                bad |= u64::from(u32::from(v) >= radix);
1521                acc.wrapping_mul(u64::from(radix))
1522                    .wrapping_add(u64::from(v))
1523            })
1524        }
1525    };
1526    let first = value(0, head);
1527    let mut len = usize::from(first != 0);
1528    let mut j = 0;
1529    let at = |j: usize| head + k * j;
1530    // SAFETY: as the caller guarantees: the number has at most as many limbs as the blocks taken,
1531    // and a group writes at most `READ_PASSES` more limbs than it has, as many as the blocks it
1532    // takes.
1533    unsafe {
1534        *x = first;
1535        while j < count {
1536            if len >= READ_WAVES && count - j >= READ_PASSES {
1537                let v: [u64; READ_PASSES] = core::array::from_fn(|i| value(at(j + i), k));
1538                len = mul_add_group(x, len, b, v);
1539                j += READ_PASSES;
1540            } else {
1541                let carry = mul_add(x, len, b, value(at(j), k));
1542                *x.add(len) = carry;
1543                len += usize::from(carry != 0);
1544                j += 1;
1545            }
1546        }
1547    }
1548    (bad == 0).then_some(len)
1549}
1550
1551/// Sets the `len` limbs at `x` to `(.. ((x b + v[0]) b + v[1]) ..) b + v[K - 1]`, the steps of
1552/// [`mul_add`] `K` times, and returns the new length. The steps of one pass wait for each other,
1553/// two additions on the carry; so the `K` passes run in waves, each a limb behind the one before
1554/// it, from which it takes its limbs in registers, and the core runs their chains side by side.
1555/// Every pass takes `len + K - 1` limbs, zeros above the number, so that their carries come out
1556/// as limbs; the last pass writes its limbs back, after the first one read them.
1557///
1558/// # Safety
1559///
1560/// The `len + K` limbs at `x` must be valid for writes, and the `len` first ones for reads.
1561#[inline(always)]
1562unsafe fn mul_add_group<const K: usize>(x: *mut u64, len: usize, b: u64, v: [u64; K]) -> usize {
1563    let n = len + K - 1;
1564    let mut carry = v;
1565    // The limb that each pass handed the next one in the last wave.
1566    let mut c = [0u64; K];
1567    // SAFETY: as the caller guarantees: in wave `t`, the first pass reads limb `t` below `len`,
1568    // the last one writes limb `t - K + 1`, below `n`, and the last carry goes to limb `n`.
1569    unsafe {
1570        // Pass `p` at limb `t - p` in wave `t`.
1571        let mut wave = |t: usize, from: usize, to: usize| {
1572            let mut p = to;
1573            while p > from {
1574                p -= 1;
1575                let input = if p > 0 {
1576                    c[p - 1]
1577                } else if t < len {
1578                    *x.add(t)
1579                } else {
1580                    0
1581                };
1582                let s = u128::from(input) * u128::from(b) + u128::from(carry[p]);
1583                carry[p] = (s >> 64) as u64;
1584                if p == K - 1 {
1585                    *x.add(t - p) = s as u64;
1586                } else {
1587                    c[p] = s as u64;
1588                }
1589            }
1590        };
1591        for t in 0..K - 1 {
1592            wave(t, 0, t + 1);
1593        }
1594        for t in K - 1..n {
1595            wave(t, 0, K);
1596        }
1597        for i in 0..K - 1 {
1598            wave(n + i, i + 1, K);
1599        }
1600        *x.add(n) = carry[K - 1];
1601        let mut top = n + 1;
1602        while top > 0 && *x.add(top - 1) == 0 {
1603            top -= 1;
1604        }
1605        top
1606    }
1607}
1608
1609/// The value of the digits `text` in `radix`, not a power of two, as a little-endian number in the
1610/// shortest form, or `None` when a character is not a digit: halves by divide and conquer from
1611/// [`READ_SPLIT`] blocks, the upper one times `b^(2^i)` plus the lower one of `k 2^i` digits; below,
1612/// block by block. `powers` holds the powers `b^(2^i)`, computed as they are first needed.
1613///
1614/// With the power `odd 256^zeros`, the upper half is multiplied by `odd` alone, and the lower one
1615/// added in `zeros` bytes up, but for its bytes below them, which are put below.
1616fn read_split(text: &[u8], radix: u32, powers: &mut Vec<Power>) -> Option<Number> {
1617    let (b, k) = block(radix);
1618    let blocks = text.len().div_ceil(k);
1619    if blocks <= READ_SPLIT {
1620        let mut x = Vec::<u64>::with_capacity(blocks + 1);
1621        // SAFETY: the vector has room for one limb a block and one more.
1622        let len = unsafe { read_blocks(text, radix, b, k, x.as_mut_ptr())? };
1623        return Some(limbs_number(
1624            x.as_mut_ptr(),
1625            len,
1626            false,
1627            ByteOrder::LittleEndian,
1628        ));
1629    }
1630    // The largest `i` whose `k 2^i` places are at most half the digits.
1631    let half = text.len() / 2;
1632    let i = largest(powers, b, k, |_, places| places <= half);
1633    let (places, zeros) = (powers[i].places, powers[i].zeros);
1634    let (high, low) = text.split_at(text.len() - places);
1635    let high = read_split(high, radix, powers)?;
1636    let low = read_split(low, radix, powers)?;
1637    let product = &high * &powers[i].odd;
1638    let mut value = low.value;
1639    let sum = if value.len() > zeros {
1640        let above = Number {
1641            value: value[zeros..].to_vec(),
1642            negative: false,
1643            byte_order: ByteOrder::LittleEndian,
1644        };
1645        &product + &above
1646    } else {
1647        product
1648    };
1649    value.resize(zeros, 0);
1650    value.extend_from_slice(&sum.value);
1651    Some(trimmed(value))
1652}
1653
1654impl core::str::FromStr for Number {
1655    type Err = ParseNumberError;
1656
1657    /// Reads a number from decimal text, as [`Number::from_str_radix`] does with radix 10, and
1658    /// builds it little-endian, the byte order of [`Number::default`].
1659    ///
1660    /// # Examples
1661    ///
1662    /// ```
1663    /// use a::math::numbers::Number;
1664    ///
1665    /// let n: Number = "-123456789012345678901234567890".parse().unwrap();
1666    /// assert!(n.is_negative());
1667    /// assert_eq!(n.to_string(), "-123456789012345678901234567890");
1668    /// assert!("12a".parse::<Number>().is_err());
1669    /// ```
1670    #[inline]
1671    fn from_str(src: &str) -> Result<Number, ParseNumberError> {
1672        Number::from_str_radix(src, 10, ByteOrder::LittleEndian)
1673    }
1674}
1675
1676/// An error from [`Number::from_str_radix`]: what was wrong with the text, from
1677/// [`kind`](Self::kind).
1678#[derive(Debug, Clone, PartialEq, Eq)]
1679pub struct ParseNumberError {
1680    kind: NumberErrorKind,
1681}
1682
1683/// What [`ParseNumberError`] found wrong with the text.
1684#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1685#[non_exhaustive]
1686pub enum NumberErrorKind {
1687    /// The text is empty.
1688    Empty,
1689    /// A character is not a digit of the radix, or the sign has no digits after it.
1690    InvalidDigit,
1691}
1692
1693impl ParseNumberError {
1694    /// What was wrong with the text.
1695    pub fn kind(&self) -> &NumberErrorKind {
1696        &self.kind
1697    }
1698}
1699
1700impl fmt::Display for ParseNumberError {
1701    /// Writes what was wrong, in the words of the primitive integers' `ParseIntError`.
1702    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1703        match self.kind {
1704            NumberErrorKind::Empty => "cannot parse integer from empty string",
1705            NumberErrorKind::InvalidDigit => "invalid digit found in string",
1706        }
1707        .fmt(f)
1708    }
1709}
1710
1711impl std::error::Error for ParseNumberError {}
1712
1713/// Writes the magnitude of `n` in `radix` through `f.pad_integral`, which adds the sign, the
1714/// `prefix` with the `#` flag, and the width, fill and alignment asked for. Up to
1715/// [`STACK_TEXT`] digits are written in a buffer on the stack, longer text in a vector.
1716fn format(
1717    n: &Number,
1718    radix: u32,
1719    prefix: &str,
1720    upper: bool,
1721    f: &mut fmt::Formatter<'_>,
1722) -> fmt::Result {
1723    let x = Operand::of(n);
1724    let bound = digits_bound(x.significant, radix);
1725    let non_negative = !n.negative || x.significant == 0;
1726    let mut stack = [MaybeUninit::<u8>::uninit(); STACK_TEXT];
1727    let mut heap = Vec::new();
1728    let dst = if bound <= STACK_TEXT {
1729        stack.as_mut_ptr().cast::<u8>()
1730    } else {
1731        heap.reserve_exact(bound);
1732        heap.as_mut_ptr()
1733    };
1734    // SAFETY: the buffer has room for the digits, which are written before they are read; they
1735    // are ASCII. `n` is borrowed while it is read.
1736    let digits = unsafe {
1737        let len = write_magnitude(x, radix, dst);
1738        let digits = core::slice::from_raw_parts_mut(dst, len);
1739        if upper {
1740            digits.make_ascii_uppercase();
1741        }
1742        core::str::from_utf8_unchecked(digits)
1743    };
1744    f.pad_integral(non_negative, prefix, digits)
1745}
1746
1747impl fmt::Display for Number {
1748    /// Writes the number in decimal: `-` for a negative number, then the digits; the formatter's
1749    /// flags, width and fill apply as they do to the primitive integers.
1750    ///
1751    /// # Examples
1752    ///
1753    /// ```
1754    /// use a::math::numbers::{ByteOrder, Number};
1755    ///
1756    /// let n = Number::new_from_i64(-1_234_567_890_123, ByteOrder::LittleEndian);
1757    /// assert_eq!(n.to_string(), "-1234567890123");
1758    /// assert_eq!(format!("{:>16}", n), "  -1234567890123");
1759    /// assert_eq!(format!("{:+}", Number::new_from_u8(7, ByteOrder::BigEndian)), "+7");
1760    /// ```
1761    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1762        format(self, 10, "", false, f)
1763    }
1764}
1765
1766impl fmt::LowerHex for Number {
1767    /// Writes the number in hexadecimal, lower-case: the sign and the digits of the magnitude, not
1768    /// a two's complement; `0x` in front with the `#` flag.
1769    ///
1770    /// # Examples
1771    ///
1772    /// ```
1773    /// use a::math::numbers::{ByteOrder, Number};
1774    ///
1775    /// let n = Number::new_from_i32(-0xBEEF, ByteOrder::BigEndian);
1776    /// assert_eq!(format!("{n:x}"), "-beef");
1777    /// assert_eq!(format!("{n:#x}"), "-0xbeef");
1778    /// ```
1779    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1780        format(self, 16, "0x", false, f)
1781    }
1782}
1783
1784impl fmt::UpperHex for Number {
1785    /// Writes the number in hexadecimal, upper-case, as [`LowerHex`](fmt::LowerHex) does.
1786    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1787        format(self, 16, "0x", true, f)
1788    }
1789}
1790
1791impl fmt::Octal for Number {
1792    /// Writes the number in octal: the sign and the digits; `0o` in front with the `#` flag.
1793    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1794        format(self, 8, "0o", false, f)
1795    }
1796}
1797
1798impl fmt::Binary for Number {
1799    /// Writes the number in binary: the sign and the digits; `0b` in front with the `#` flag.
1800    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1801        format(self, 2, "0b", false, f)
1802    }
1803}