mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-29 03:04:38 +08:00
Clear up format_float_as_exponent
This commit is contained in:
1 parent
29859b47e4
commit
db976ddc70
3 files changed
+55
-21
No files matched your search
+36
-12
@@ -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
@@ -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
@@ -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()),
|
||||
|
||||
Reference in new issue
Block a user