Skip to main content

strtofr

Function strtofr 

Source
pub fn strtofr(
    s: &str,
    base: u8,
    prec: u64,
    rm: RoundingMode,
) -> (Float, Ordering, usize)
Expand description

Converts a string to a Float, reading as much of it as forms a valid number.

The value is the exact value of the digits read, rounded once to prec bits with rm. Returns that value, the Ordering of it against the string’s exact value, and the number of bytes consumed, which is zero if the string does not begin with a valid number (in which case the value is zero and the Ordering is Equal).

This is MPFR’s grammar rather than Malachite’s, so it differs from from_sci_string_prec_round in what it accepts; see from_string for the Malachite side. Leading whitespace is skipped, then an optional sign, then:

  • nan or inf or infinity, case-insensitively, when base is 16 or less, or @nan@ or @inf@ in any base. A nan may be followed by a parenthesized run of alphanumerics and underscores, as in nan(_char_sequence).
  • Otherwise digits, with an optional point among them. Digits above 9 are the letters, with the case ignored when base is 36 or less; above that, az continue the sequence after AZ, giving values 36 to 61.

A base of 0 means the base is taken from a 0x or 0b prefix, defaulting to 10. Those prefixes are also accepted when base is 16 or 2 respectively.

An exponent may follow the digits: e or E when base is 10 or less, p or P when base is 2 or 16, and @ in any base. An e or @ exponent is a power of base, while a p exponent is a power of 2. The exponent itself is always read in base 10, and saturates rather than wrapping.

§Worst-case complexity

$T(n) = O(n (\log n)^2 \log\log n)$

$M(n) = O(n \log n)$

where $T$ is time, $M$ is additional memory, and $n$ is max(s.len(), prec).

§Panics

Panics if base is 1 or greater than 62, if prec is zero, or if rm is Exact but the string’s value is not exactly representable with prec bits.

§Examples

use core::cmp::Ordering::*;
use malachite_base::rounding_modes::RoundingMode::*;
use malachite_float::float::conversion::string::strtofr::strtofr;

let s = |s, base, prec, rm| {
    let (x, o, len) = strtofr(s, base, prec, rm);
    (x.to_string(), o, len)
};

assert_eq!(s("1.5", 10, 10, Nearest), ("1.5000".to_string(), Equal, 3));
assert_eq!(
    s("ff", 16, 53, Nearest),
    ("255.00000000000000".to_string(), Equal, 2)
);

// 0.1 is not representable in binary, so it is rounded and the `Ordering` gives the direction.
assert_eq!(s("0.1", 10, 4, Floor), ("0.0938".to_string(), Less, 3));
assert_eq!(s("0.1", 10, 4, Ceiling), ("0.102".to_string(), Greater, 3));

// A base of 0 takes the base from the prefix.
assert_eq!(
    s("0b1.1", 0, 53, Nearest),
    ("1.5000000000000000".to_string(), Equal, 5)
);

// `e` is a power of the base and `p` a power of two; `@` works in any base.
assert_eq!(
    s("1e5", 10, 53, Nearest),
    ("100000.00000000000".to_string(), Equal, 3)
);
assert_eq!(
    s("1@5", 16, 53, Nearest),
    ("1048576.0000000000".to_string(), Equal, 3)
);

// The special values, and a string that is not a number at all.
assert_eq!(s("nan", 10, 53, Nearest), ("NaN".to_string(), Equal, 3));
assert_eq!(
    s("-inf", 10, 53, Nearest),
    ("-Infinity".to_string(), Equal, 4)
);
assert_eq!(s("abc", 10, 53, Nearest), ("0.0".to_string(), Equal, 0));

This is mpfr_strtofr from strtofr.c, MPFR 4.3.0.