#string #convert-string #convert #float #format-string #string-representation #formatting

yanked flt2dec2flt

Low-level functions to convert floating point numbers to strings and vice versa

0.1.0 Mar 28, 2020

#45 in #convert-string

MIT/Apache

185KB
3.5K SLoC

flt2dec2flt

Crate API License TravisCI Build Status

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

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);

No runtime deps