mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-28 18:59:04 +08:00
Unify general format of floating numbers
This commit is contained in:
1 parent
6ca53213e8
commit
8c96bd680f
3 files changed
+39
-35
No files matched your search
@@ -128,6 +128,29 @@ pub fn format_exponent(precision: usize, magnitude: f64, case: Case) -> String {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn format_general(precision: usize, magnitude: f64, case: Case) -> 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();
|
||||
if exponent < -4 || exponent >= (precision as i64) {
|
||||
let e = match case {
|
||||
Case::Lower => 'e',
|
||||
Case::Upper => 'E',
|
||||
};
|
||||
format!("{}{}{:+#03}", base, e, exponent)
|
||||
} else {
|
||||
format!("{}", magnitude)
|
||||
}
|
||||
}
|
||||
magnitude if magnitude.is_nan() => format_nan(case),
|
||||
magnitude if magnitude.is_infinite() => format_inf(case),
|
||||
_ => "".to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_string(value: f64) -> String {
|
||||
let lit = format!("{:e}", value);
|
||||
if let Some(position) = lit.find('e') {
|
||||
|
||||
+6
-29
@@ -293,24 +293,6 @@ impl CFormatSpec {
|
||||
}
|
||||
}
|
||||
|
||||
fn normalize_float(&self, num: f64) -> (f64, i32) {
|
||||
let mut fraction = num;
|
||||
let mut exponent = 0;
|
||||
loop {
|
||||
if fraction >= 10.0 {
|
||||
fraction /= 10.0;
|
||||
exponent += 1;
|
||||
} else if fraction < 1.0 && fraction > 0.0 {
|
||||
fraction *= 10.0;
|
||||
exponent -= 1;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
(fraction, exponent)
|
||||
}
|
||||
|
||||
pub(crate) fn format_float(&self, num: f64) -> String {
|
||||
let sign_string = if num.is_sign_positive() {
|
||||
self.flags.sign_string()
|
||||
@@ -337,17 +319,12 @@ impl CFormatSpec {
|
||||
}
|
||||
CFormatType::Float(CFloatType::General(case)) => {
|
||||
let precision = if precision == 0 { 1 } else { precision };
|
||||
let (fraction, exponent) = self.normalize_float(num.abs());
|
||||
if exponent < -4 || exponent >= (precision as i32) {
|
||||
let case = match case {
|
||||
CFormatCase::Lowercase => 'e',
|
||||
CFormatCase::Uppercase => 'E',
|
||||
};
|
||||
format!("{}{}{:+03}", fraction, case, exponent)
|
||||
} else {
|
||||
let magnitude = num.abs();
|
||||
format!("{}", magnitude)
|
||||
}
|
||||
let case = match case {
|
||||
CFormatCase::Lowercase => float_ops::Case::Lower,
|
||||
CFormatCase::Uppercase => float_ops::Case::Upper,
|
||||
};
|
||||
let magnitude = num.abs();
|
||||
float_ops::format_general(precision, magnitude, case)
|
||||
}
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
+10
-6
@@ -369,12 +369,16 @@ impl FormatSpec {
|
||||
Some(FormatType::Number) => {
|
||||
Err("Format code 'n' for object of type 'float' not implemented yet")
|
||||
}
|
||||
Some(FormatType::GeneralFormatUpper) => {
|
||||
Err("Format code 'G' for object of type 'float' not implemented yet")
|
||||
}
|
||||
Some(FormatType::GeneralFormatLower) => {
|
||||
Err("Format code 'g' for object of type 'float' not implemented yet")
|
||||
}
|
||||
Some(FormatType::GeneralFormatUpper) => Ok(float_ops::format_general(
|
||||
precision,
|
||||
magnitude,
|
||||
float_ops::Case::Upper,
|
||||
)),
|
||||
Some(FormatType::GeneralFormatLower) => Ok(float_ops::format_general(
|
||||
precision,
|
||||
magnitude,
|
||||
float_ops::Case::Lower,
|
||||
)),
|
||||
Some(FormatType::ExponentUpper) => Ok(float_ops::format_exponent(
|
||||
precision,
|
||||
magnitude,
|
||||
|
||||
Reference in new issue
Block a user