pub(crate) fn write_float(x: f64, nan: &str, inf: &str, neg_inf: &str, out: &mut String) {
if x.is_nan() {
out.push_str(nan);
} else if x.is_infinite() {
out.push_str(if x > 0.0 { inf } else { neg_inf });
} else {
let s = x.to_string();
if s.contains('.') || s.contains('e') || s.contains('E') {
out.push_str(&s);
} else {
out.push_str(&s);
out.push_str(".0");
}
}
}
pub(crate) fn float_to_string(x: f64, nan: &str, inf: &str, neg_inf: &str) -> String {
let mut out = String::new();
write_float(x, nan, inf, neg_inf, &mut out);
out
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn write_float_covers_every_branch() {
let mut out = String::new();
write_float(f64::NAN, "NaN", "Infinity", "-Infinity", &mut out);
assert_eq!(out, "NaN");
out.clear();
write_float(f64::INFINITY, "NaN", "Infinity", "-Infinity", &mut out);
assert_eq!(out, "Infinity");
out.clear();
write_float(f64::NEG_INFINITY, "NaN", "Infinity", "-Infinity", &mut out);
assert_eq!(out, "-Infinity");
out.clear();
write_float(1.5, "NaN", "Infinity", "-Infinity", &mut out);
assert_eq!(out, "1.5");
out.clear();
write_float(2.0, "NaN", "Infinity", "-Infinity", &mut out);
assert_eq!(out, "2.0");
}
#[test]
fn write_float_uses_the_caller_supplied_spelling_table() {
let mut out = String::new();
write_float(f64::NAN, ".nan", ".inf", "-.inf", &mut out);
assert_eq!(out, ".nan");
out.clear();
write_float(f64::NEG_INFINITY, ".nan", ".inf", "-.inf", &mut out);
assert_eq!(out, "-.inf");
}
#[test]
fn round_trips_integral_float_at_and_above_1e17_boundary_issue_46() {
for x in [1.0e17, 1.0e18, -1.23e17, 9.9e16_f64] {
let s = float_to_string(x, "nan", "inf", "-inf");
assert!(s.contains('.'), "x={x} s={s}");
let back: f64 = s.parse().unwrap();
assert_eq!(back, x, "x={x} s={s}");
}
}
#[test]
fn float_to_string_matches_write_float() {
assert_eq!(float_to_string(1.5, "nan", "inf", "-inf"), "1.5");
assert_eq!(float_to_string(f64::NAN, "nan", "inf", "-inf"), "nan");
assert_eq!(float_to_string(f64::INFINITY, "nan", "inf", "-inf"), "inf");
assert_eq!(
float_to_string(f64::NEG_INFINITY, "nan", "inf", "-inf"),
"-inf"
);
}
}