1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
//! Compact number formatting.
//!
//! Turns large integers and floats into short or long human-readable forms.
//!
//! # Quick start
//!
//! ```rust
//! use humfmt::{number, number_with, NumberOptions};
//!
//! assert_eq!(number(15_320).to_string(), "15.3K");
//! assert_eq!(number(1_500_000).to_string(), "1.5M");
//! assert_eq!(number(-12_500).to_string(), "-12.5K");
//!
//! let opts = NumberOptions::new().long_units();
//! assert_eq!(number_with(15_320, opts).to_string(), "15.3 thousand");
//! ```
//!
//! # Edge case behaviour
//!
//! | Input | Default output | Notes |
//! |---:|---|---|
//! | `0` | `"0"` | No suffix, no sign |
//! | `1` | `"1"` | Below threshold |
//! | `999` | `"999"` | Below threshold |
//! | `1_000` | `"1K"` | First compact threshold |
//! | `999_950` | `"1M"` | Rounds up across suffix boundary |
//! | `-1` | `"-1"` | Sign preserved |
//! | `-12_500` | `"-12.5K"` | Sign + compact |
//! | `i128::MIN` | `"-170.1Dc"` | No panic, no overflow |
//! | `u128::MAX` | `"340.3Dc"` | No panic, no overflow |
//! | `0.0` | `"0"` | |
//! | `-0.0` | `"0"` | Negative zero suppressed |
//! | `-0.004` | `"0"` | Rounds to zero, sign suppressed |
//! | `f64::INFINITY` | `"inf"` | |
//! | `f64::NEG_INFINITY` | `"-inf"` | |
//! | `f64::NAN` | `"NaN"` | |
//!
//! # Suffix table
//!
//! | Index | Magnitude | Short | Long |
//! |:---:|---:|---|---|
//! | 0 | 1 | `""` | `""` |
//! | 1 | 10^3 | `K` | ` thousand` |
//! | 2 | 10^6 | `M` | ` million` |
//! | 3 | 10^9 | `B` | ` billion` |
//! | 4 | 10^12 | `T` | ` trillion` |
//! | 5 | 10^15 | `Qa` | ` quadrillion` |
//! | 6 | 10^18 | `Qi` | ` quintillion` |
//! | 7 | 10^21 | `Sx` | ` sextillion` |
//! | 8 | 10^24 | `Sp` | ` septillion` |
//! | 9 | 10^27 | `Oc` | ` octillion` |
//! | 10 | 10^30 | `No` | ` nonillion` |
//! | 11 | 10^33 | `Dc` | ` decillion` |
//!
//! # Float precision limits
//!
//! `f64` cannot exactly represent integers above `2^53`. For very large float
//! inputs, compact formatting may lose a few digits in the integer part before
//! scaling. This is a known limitation of IEEE 754 double precision and is
//! acceptable for display purposes.
pub use NumberDisplay;
pub use NumberOptions;
pub use NumberLike;
/// Creates a human-readable compact number formatter using default options.
///
/// Accepts all integer primitives (`i8`..`i128`, `u8`..`u128`, `isize`, `usize`)
/// and floats (`f32`, `f64`).
///
/// # Examples
///
/// ```rust
/// assert_eq!(humfmt::number(15_320).to_string(), "15.3K");
/// assert_eq!(humfmt::number(1_500_000).to_string(), "1.5M");
/// assert_eq!(humfmt::number(-12_500).to_string(), "-12.5K");
/// assert_eq!(humfmt::number(0).to_string(), "0");
/// assert_eq!(humfmt::number(f64::NAN).to_string(), "NaN");
/// ```
/// Creates a human-readable compact number formatter with custom options.
///
/// # Examples
///
/// ```rust
/// use humfmt::NumberOptions;
///
/// let out = humfmt::number_with(15_320, NumberOptions::new().long_units());
/// assert_eq!(out.to_string(), "15.3 thousand");
///
/// let out = humfmt::number_with(15_320, NumberOptions::new().precision(2));
/// assert_eq!(out.to_string(), "15.32K");
/// ```