| 1 | //! [![github]](https://github.com/dtolnay/ryu) [![crates-io]](https://crates.io/crates/ryu) [![docs-rs]](https://docs.rs/ryu) |
| 2 | //! |
| 3 | //! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github |
| 4 | //! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust |
| 5 | //! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs |
| 6 | //! |
| 7 | //! <br> |
| 8 | //! |
| 9 | //! Pure Rust implementation of Ryū, an algorithm to quickly convert floating |
| 10 | //! point numbers to decimal strings. |
| 11 | //! |
| 12 | //! The PLDI'18 paper [*Ryū: fast float-to-string conversion*][paper] by Ulf |
| 13 | //! Adams includes a complete correctness proof of the algorithm. The paper is |
| 14 | //! available under the creative commons CC-BY-SA license. |
| 15 | //! |
| 16 | //! This Rust implementation is a line-by-line port of Ulf Adams' implementation |
| 17 | //! in C, [https://github.com/ulfjack/ryu][upstream]. |
| 18 | //! |
| 19 | //! [paper]: https://dl.acm.org/citation.cfm?id=3192369 |
| 20 | //! [upstream]: https://github.com/ulfjack/ryu |
| 21 | //! |
| 22 | //! # Example |
| 23 | //! |
| 24 | //! ``` |
| 25 | //! fn main() { |
| 26 | //! let mut buffer = ryu::Buffer::new(); |
| 27 | //! let printed = buffer.format(1.234); |
| 28 | //! assert_eq!(printed, "1.234" ); |
| 29 | //! } |
| 30 | //! ``` |
| 31 | //! |
| 32 | //! ## Performance (lower is better) |
| 33 | //! |
| 34 | //!  |
| 35 | //! |
| 36 | //! You can run upstream's benchmarks with: |
| 37 | //! |
| 38 | //! ```console |
| 39 | //! $ git clone https://github.com/ulfjack/ryu c-ryu |
| 40 | //! $ cd c-ryu |
| 41 | //! $ bazel run -c opt //ryu/benchmark |
| 42 | //! ``` |
| 43 | //! |
| 44 | //! And the same benchmark against our implementation with: |
| 45 | //! |
| 46 | //! ```console |
| 47 | //! $ git clone https://github.com/dtolnay/ryu rust-ryu |
| 48 | //! $ cd rust-ryu |
| 49 | //! $ cargo run --example upstream_benchmark --release |
| 50 | //! ``` |
| 51 | //! |
| 52 | //! These benchmarks measure the average time to print a 32-bit float and average |
| 53 | //! time to print a 64-bit float, where the inputs are distributed as uniform random |
| 54 | //! bit patterns 32 and 64 bits wide. |
| 55 | //! |
| 56 | //! The upstream C code, the unsafe direct Rust port, and the safe pretty Rust API |
| 57 | //! all perform the same, taking around 21 nanoseconds to format a 32-bit float and |
| 58 | //! 31 nanoseconds to format a 64-bit float. |
| 59 | //! |
| 60 | //! There is also a Rust-specific benchmark comparing this implementation to the |
| 61 | //! standard library which you can run with: |
| 62 | //! |
| 63 | //! ```console |
| 64 | //! $ cargo bench |
| 65 | //! ``` |
| 66 | //! |
| 67 | //! The benchmark shows Ryū approximately 2-5x faster than the standard library |
| 68 | //! across a range of f32 and f64 inputs. Measurements are in nanoseconds per |
| 69 | //! iteration; smaller is better. |
| 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.18" )] |
| 85 | #![cfg_attr (not(check_cfg), allow(unexpected_cfgs))] |
| 86 | #![allow ( |
| 87 | clippy::cast_lossless, |
| 88 | clippy::cast_possible_truncation, |
| 89 | clippy::cast_possible_wrap, |
| 90 | clippy::cast_sign_loss, |
| 91 | clippy::checked_conversions, |
| 92 | clippy::doc_markdown, |
| 93 | clippy::expl_impl_clone_on_copy, |
| 94 | clippy::if_not_else, |
| 95 | clippy::many_single_char_names, |
| 96 | clippy::missing_panics_doc, |
| 97 | clippy::module_name_repetitions, |
| 98 | clippy::must_use_candidate, |
| 99 | clippy::needless_doctest_main, |
| 100 | clippy::similar_names, |
| 101 | clippy::too_many_lines, |
| 102 | clippy::unreadable_literal, |
| 103 | clippy::unseparated_literal_suffix, |
| 104 | clippy::wildcard_imports |
| 105 | )] |
| 106 | |
| 107 | mod buffer; |
| 108 | mod common; |
| 109 | mod d2s; |
| 110 | #[cfg (not(feature = "small" ))] |
| 111 | mod d2s_full_table; |
| 112 | mod d2s_intrinsics; |
| 113 | #[cfg (feature = "small" )] |
| 114 | mod d2s_small_table; |
| 115 | mod digit_table; |
| 116 | mod f2s; |
| 117 | mod f2s_intrinsics; |
| 118 | mod pretty; |
| 119 | |
| 120 | pub use crate::buffer::{Buffer, Float}; |
| 121 | |
| 122 | /// Unsafe functions that mirror the API of the C implementation of Ryū. |
| 123 | pub mod raw { |
| 124 | pub use crate::pretty::{format32, format64}; |
| 125 | } |
| 126 | |