ryu/lib.rs
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")]
92extern crate no_panic;
93
94mod buffer;
95mod common;
96mod d2s;
97#[cfg(not(feature = "small"))]
98mod d2s_full_table;
99mod d2s_intrinsics;
100#[cfg(feature = "small")]
101mod d2s_small_table;
102mod digit_table;
103mod f2s;
104mod pretty;
105
106pub use buffer::{Buffer, Float};
107
108/// Unsafe functions that mirror the API of the C implementation of Ryū.
109pub mod raw {
110 pub use pretty::{format32, format64};
111}