1 //! Pure Rust implementation of Ryū, an algorithm to quickly convert floating
2 //! point numbers to decimal strings.
3 //!
4 //! The PLDI'18 paper [*Ryū: fast float-to-string conversion*][paper] by Ulf
5 //! Adams includes a complete correctness proof of the algorithm. The paper is
6 //! available under the creative commons CC-BY-SA license.
7 //!
8 //! This Rust implementation is a line-by-line port of Ulf Adams' implementation
9 //! in C, [https://github.com/ulfjack/ryu][upstream].
10 //!
11 //! [paper]: https://dl.acm.org/citation.cfm?id=3192369
12 //! [upstream]: https://github.com/ulfjack/ryu
13 //!
14 //! # Example
15 //!
16 //! ```edition2018
17 //! fn main() {
18 //!     let mut buffer = ryu::Buffer::new();
19 //!     let printed = buffer.format(1.234);
20 //!     assert_eq!(printed, "1.234");
21 //! }
22 //! ```
23 //!
24 //! ## Performance
25 //!
26 //! You can run upstream's benchmarks with:
27 //!
28 //! ```console
29 //! $ git clone https://github.com/ulfjack/ryu c-ryu
30 //! $ cd c-ryu
31 //! $ bazel run -c opt //ryu/benchmark
32 //! ```
33 //!
34 //! And the same benchmark against our implementation with:
35 //!
36 //! ```console
37 //! $ git clone https://github.com/dtolnay/ryu rust-ryu
38 //! $ cd rust-ryu
39 //! $ cargo run --example upstream_benchmark --release
40 //! ```
41 //!
42 //! These benchmarks measure the average time to print a 32-bit float and average
43 //! time to print a 64-bit float, where the inputs are distributed as uniform random
44 //! bit patterns 32 and 64 bits wide.
45 //!
46 //! The upstream C code, the unsafe direct Rust port, and the safe pretty Rust API
47 //! all perform the same, taking around 21 nanoseconds to format a 32-bit float and
48 //! 31 nanoseconds to format a 64-bit float.
49 //!
50 //! There is also a Rust-specific benchmark comparing this implementation to the
51 //! standard library which you can run with:
52 //!
53 //! ```console
54 //! $ cargo bench
55 //! ```
56 //!
57 //! The benchmark shows Ryu approximately 4-10x faster than the standard library
58 //! across a range of f32 and f64 inputs. Measurements are in nanoseconds per
59 //! iteration; smaller is better.
60 //!
61 //! | type=f32 | 0.0  | 0.1234 | 2.718281828459045 | f32::MAX |
62 //! |:--------:|:----:|:------:|:-----------------:|:--------:|
63 //! | RYU      | 3ns  | 28ns   | 23ns              | 22ns     |
64 //! | STD      | 40ns | 106ns  | 128ns             | 110ns    |
65 //!
66 //! | type=f64 | 0.0  | 0.1234 | 2.718281828459045 | f64::MAX |
67 //! |:--------:|:----:|:------:|:-----------------:|:--------:|
68 //! | RYU      | 3ns  | 50ns   | 35ns              | 32ns     |
69 //! | STD      | 39ns | 105ns  | 128ns             | 202ns    |
70 //!
71 //! ## Formatting
72 //!
73 //! This library tends to produce more human-readable output than the standard
74 //! library's to\_string, which never uses scientific notation. Here are two
75 //! examples:
76 //!
77 //! - *ryu:* 1.23e40, *std:* 12300000000000000000000000000000000000000
78 //! - *ryu:* 1.23e-40, *std:* 0.000000000000000000000000000000000000000123
79 //!
80 //! Both libraries print short decimals such as 0.0000123 without scientific
81 //! notation.
82 
83 #![no_std]
84 #![doc(html_root_url = "https://docs.rs/ryu/1.0.3")]
85 #![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))]
86 #![cfg_attr(
87     feature = "cargo-clippy",
88     allow(cast_lossless, many_single_char_names, unreadable_literal,)
89 )]
90 
91 #[cfg(feature = "no-panic")]
92 extern crate no_panic;
93 
94 mod buffer;
95 mod common;
96 mod d2s;
97 #[cfg(not(feature = "small"))]
98 mod d2s_full_table;
99 mod d2s_intrinsics;
100 #[cfg(feature = "small")]
101 mod d2s_small_table;
102 mod digit_table;
103 mod f2s;
104 mod pretty;
105 
106 pub use buffer::{Buffer, Float};
107 
108 /// Unsafe functions that mirror the API of the C implementation of Ryū.
109 pub mod raw {
110     pub use pretty::{format32, format64};
111 }
112