Fast lexical conversion routines for both std and no_std environments. Lexical provides routines to convert numbers to and from decimal strings. Lexical also supports non-base 10 numbers, for both integers and floats. Lexical is simple to use, and exports only 6 functions in the high-level API.
Table of Contents
Add lexical to your Cargo.toml
:
yaml
[dependencies]
lexical = "1"
And get started using lexical:
```rust extern crate lexical;
// Number to string lexical::tostring(3.0); // "3.0", always has a fraction suffix, lexical::tostring(3); // "3" lexical::tostringradix(3.0, 2); // "11.0", non-base 10 representation. lexical::tostringradix(1.5, 2); // "1.1" lexical::tostringradix(1.25, 2); // "1.01"
// String to number.
let i: i32 = lexical::parse("3"); // 3, auto-type deduction.
let f: f32 = lexical::parse("3.5"); // 3.5
let d = lexical::parse::
Lexical's parsers can be either error-checked and unchecked. The unchecked parsers continue to parse until they encounter invalid data or overflow, returning a number was successfully parsed up until that point. This is analogous to C's strtod
, which may not be desirable for many applications. Therefore, lexical also includes checked parsers, which ensure the entire buffer is used while parsing, without discarding characters, and that the resulting number did not overflow. Upon erroring, the checked parsers will return the an enum indicating overflow or the index where the first invalid digit was found.
```rust // This will return Err(Error(ErrorKind::InvalidDigit(3))), indicating // the first invalid character occurred at the index 3 in the input // string (the space character). let x: i32 = lexical::try_parse("123 456");
// This will return Ok(123), since that is the value found before invalid // character was encountered. let x: i32 = lexical::parse("123 456"); ```
The following benchmarks measure the time it takes to convert 10,000 random values, for different types. The values were randomly generated using NumPy, and run in both std (rustc 1.29.2) and no_std (rustc 1.31.0) contexts (only std is shown) on an x86-64 Intel processor. More information on these benchmarks can be found in the benches folder and in the source code for the respective algorithms. Adding the flags "target-cpu=native" and "link-args=-s" were also used, however, they minimally affected the relative performance difference between different lexical conversion implementations.
For all the following benchmarks, lower is better.
Float to String
Integer To String
String to Float
String to Integer
For Float-To-String conversions, lexical uses one of three backends: an internal, Grisu2 algorithm (~99.5% correct), an external, Grisu3 algorithm (100% correct), and an external, Ryu algorithm (100% correct, ~2x as fast).
Lexical's documentation can be found on docs.rs.
Lexical heavily uses unsafe code for performance, and therefore may introduce memory-safety issues. Although the code is tested with wide variety of inputs to minimize the risk of memory-safety bugs, no guarantees are made and you should use it at your own risk.
For float-parsing, lexical uses native floats for intermediate values, rather than arbitrary-precision integers, leading to fairly minor rounding (up to 1e-16), meaning that the float parser is not completely correct (for example, 1.2345e-308 is parsed as 1.2344999999999994e-308).
Finally, for non-base10 floats, lexical's float-to-string implementations may lead to fairly lossy rounding for a small subset of inputs (up to 0.1% of the total value).
For more information on the Grisu2 and Grisu3 algorithms, see Printing Floating-Point Numbers Quickly and Accurately with Integers.
For more information on the Ryu algorithm, see Ryƫ: fast float-to-string conversion.
Lexical is dual licensed under the Apache 2.0 license as well as the MIT license. See the LICENCE-MIT and the LICENCE-APACHE files for the licenses.
Lexical also ports some code from V8 and fpconv, and therefore might be subject to the terms of a 3-clause BSD license.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in lexical by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.