0.1.0 |
|
---|
#45 in #convert-string
185KB
3.5K
SLoC
flt2dec2flt
This crate provides low-level functions to convert floating point
numbers (f32
and f64
) to decimal strings and vice versa.
License
This project is licensed under either of
- Apache License, Version 2.0, (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
lib.rs
:
This crate provides low-level functions to convert floating point
numbers (f32
and f64
) to decimal strings and vice versa.
Implementing accurate float-string conversion is non-trivial (see
for example "Printing floating-point numbers: An always correct
method" by Marc Andrysco, Ranjit Jhala and Sorin Lerner). The Rust
Standard Library internally uses complex algorithms (found in
libcore/num
) to fulfill this purpose, but they are not exposed
and can only be used through FromStr::from_str
, ToString::to_string
or Display::fmt
.
These functions impose a format on the string representation
of floating point numbers, which may not always be suitable for you.
For example, you may want to write 1.2 * 10^4
instead of 1.2e4
.
This crate exposes the core algorithms, allowing you to implement your custom float-string conversions without worrying about complex mathematical part.
The functionality of this crate is provided through the FloatExt
trait, which is implemented for f32
and f64
.
Minimum Rust version
The minimum Rust version required by this crate is 1.34.
Example (float to string)
// Let's say we want to convert this value to a string
// in exponential form.
let value = 1.25e20;
// Using the standard library, you can use `format!("{:e}")`:
assert_eq!(format!("{:e}", value), "1.25e20");
// It also allows tu use a capital 'E':
assert_eq!(format!("{:E}", value), "1.25E20");
// or to include an explicit '+':
assert_eq!(format!("{:+e}", value), "+1.25e20");
// or to used a fixed number of digits:
assert_eq!(format!("{:.04e}", value), "1.2500e20");
// However, besides those options, `format!` imposes the
// format of the string representation of the floating point
// number (using `.` as decimal separator and `e` or `E` as
// exponential separator).
// This crate provides low-level functions to conver floating point
// numbers to strings without an imposed format.
use flt2dec2flt::FloatExt as _;
// The `FloatExt::preformat_*` functions pre-converts the floating
// point numbers into string, providing a decomposed intermediate
// result.
let mut buf = [0; flt2dec2flt::PREFORMAT_SHORTEST_BUF_LEN];
// You could also use `f32::preformat_shortest(value, &mut buf)`
let preformatted = value.preformat_shortest(&mut buf);
// `false` means the the number is positive, `b"125"` are the
// significant digits and `21` is the exponent (such as
// `1.25e20 == 0.125e21`)
assert_eq!(preformatted, flt2dec2flt::PreFormatted::Finite(false, b"125", 21));
// From this decomposed form, you can now build your custom string
// representation of the floating point number.
Example (string to float)
use std::str::FromStr as _;
// Let's say you want to convert a string to a floating
// point number.
// Using the standard library, you can use `FromStr::from_str`:
assert_eq!(f32::from_str("1.25e20").unwrap(), 1.25e20);
// However, this function imposes the format of the input string.
// This crate provides functions to convert a pre-parsed string to
// a floating.
use flt2dec2flt::FloatExt as _;
// You have to implement your pre-parsing based on your string format.
// So, `1.25e20` (or `1.25*10^20`) would be pre-parsed as:
let preparsed = flt2dec2flt::PreParsed {
// positive
sign: false,
// digits of the integer part
int_digits: b"1",
// digits of the fractional part
frac_digits: b"25",
// exponent
exp: 20,
};
// Which can be converted to a floating point number:
assert_eq!(f32::from_preparsed(preparsed).unwrap(), 1.25e20);