Unify general format of floating numbers

This commit is contained in:
ChJR committed 2020-11-10 01:56:08 +09:00
1 parent 6ca53213e8
commit 8c96bd680f
3 files changed
+39 -35

No files matched your search

+23
View File
@@ -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
View File
@@ -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
View File
@@ -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,