Clear up format_float_as_exponent

This commit is contained in:
ChJR committed 2020-11-10 00:57:32 +09:00
1 parent 29859b47e4
commit db976ddc70
3 files changed
+55 -21

No files matched your search

+36 -12
View File
@@ -83,21 +83,45 @@ pub fn is_integer(v: f64) -> bool {
(v - v.round()).abs() < std::f64::EPSILON
}
#[derive(Debug)]
pub enum FloatFormatCase {
Lower,
Upper,
}
fn format_nan(case: FloatFormatCase) -> String {
let nan = match case {
FloatFormatCase::Lower => "nan",
FloatFormatCase::Upper => "NAN",
};
nan.to_string()
}
fn format_inf(case: FloatFormatCase) -> String {
let inf = match case {
FloatFormatCase::Lower => "inf",
FloatFormatCase::Upper => "INF",
};
inf.to_string()
}
// Formats floats into Python style exponent notation, by first formatting in Rust style
// exponent notation (`1.0000e0`), then convert to Python style (`1.0000e+00`).
pub fn format_float_as_exponent(precision: usize, magnitude: f64) -> String {
if magnitude.is_nan() {
return "nan".to_string();
pub fn format_float_as_exponent(precision: usize, magnitude: f64, case: FloatFormatCase) -> String {
match magnitude {
magnitude if magnitude.is_finite() => {
let r_exp = format!("{:.*e}", precision, magnitude);
let mut parts = r_exp.splitn(2, 'e');
let base = parts.next().unwrap();
let exponent = parts.next().unwrap().parse::<i64>().unwrap();
format!("{}e{:+#03}", base, exponent)
}
magnitude if magnitude.is_nan() => format_nan(case),
magnitude if magnitude.is_infinite() => format_inf(case),
_ => "".to_string(),
}
if magnitude.is_infinite() {
return "inf".to_string();
}
let r_exp = format!("{:.*e}", precision, magnitude);
let mut parts = r_exp.splitn(2, 'e');
let base = parts.next().unwrap();
let exponent = parts.next().unwrap().parse::<i64>().unwrap();
format!("{}e{:+#03}", base, exponent)
}
pub fn to_string(value: f64) -> String {
+9 -3
View File
@@ -250,7 +250,7 @@ impl CFormatSpec {
"-"
};
let magnitude_string = match self.format_type {
let magnitude_string = match &self.format_type {
CFormatType::Float(CFloatType::PointDecimal(_)) => {
let precision = match self.precision {
Some(CFormatQuantity::Amount(p)) => p,
@@ -259,13 +259,19 @@ impl CFormatSpec {
let magnitude = num.abs();
Ok(format!("{:.*}", precision, magnitude))
}
CFormatType::Float(CFloatType::Exponent(_)) => {
CFormatType::Float(CFloatType::Exponent(case)) => {
let precision = match self.precision {
Some(CFormatQuantity::Amount(p)) => p,
_ => 6,
};
let magnitude = num.abs();
Ok(float_ops::format_float_as_exponent(precision, magnitude))
let float_case = match case {
CFormatCase::Lowercase => float_ops::FloatFormatCase::Lower,
CFormatCase::Uppercase => float_ops::FloatFormatCase::Upper,
};
Ok(float_ops::format_float_as_exponent(
precision, magnitude, float_case,
))
}
CFormatType::Float(CFloatType::General(_)) => {
Err("Not yet implemented for %g and %G".to_owned())
+10 -6
View File
@@ -375,12 +375,16 @@ impl FormatSpec {
Some(FormatType::GeneralFormatLower) => {
Err("Format code 'g' for object of type 'float' not implemented yet")
}
Some(FormatType::ExponentUpper) => {
Ok(float_ops::format_float_as_exponent(precision, magnitude).to_uppercase())
}
Some(FormatType::ExponentLower) => {
Ok(float_ops::format_float_as_exponent(precision, magnitude).to_lowercase())
}
Some(FormatType::ExponentUpper) => Ok(float_ops::format_float_as_exponent(
precision,
magnitude,
float_ops::FloatFormatCase::Upper,
)),
Some(FormatType::ExponentLower) => Ok(float_ops::format_float_as_exponent(
precision,
magnitude,
float_ops::FloatFormatCase::Lower,
)),
Some(FormatType::Percentage) => match magnitude {
magnitude if magnitude.is_nan() => Ok("nan%".to_owned()),
magnitude if magnitude.is_infinite() => Ok("inf%".to_owned()),