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