#1224 Add formating for floating point and test

Just supports "%f" types
This commit is contained in:
MinGyo Jung
2019-08-15 17:39:03 +09:00
parent d508f8ad7c
commit 1114d27e28
2 changed files with 83 additions and 0 deletions

View File

@@ -209,6 +209,41 @@ impl CFormatSpec {
self.fill_string(format!("{}{}", prefix, magnitude_string), ' ', None)
}
}
pub fn format_float(&self, num: f64) -> String {
let magnitude = num.abs();
let sign_string = match num.is_sign_positive() {
false => "-",
true => {
if self.flags.contains(CConversionFlags::SIGN_CHAR) {
"+"
} else if self.flags.contains(CConversionFlags::BLANK_SIGN) {
" "
} else {
""
}
}
};
// TODO: Support precision
let magnitude_string = format!("{:.6}", magnitude);
if self.flags.contains(CConversionFlags::ZERO_PAD) {
let fill_char = if !self.flags.contains(CConversionFlags::LEFT_ADJUST) {
'0'
} else {
' '
};
format!(
"{}{}",
sign_string,
self.fill_string(magnitude_string, fill_char, Some(sign_string.chars().count()))
)
} else {
self.fill_string(format!("{}{}", sign_string, magnitude_string), ' ', None)
}
}
}
#[derive(Debug, PartialEq)]
@@ -761,6 +796,41 @@ mod tests {
.format_number(&BigInt::from(0x1337)),
"0x1337 ".to_string()
);
assert_eq!(
"%f"
.parse::<CFormatSpec>()
.unwrap()
.format_float(f64::from(1.2345)),
"1.234500".to_string()
);
assert_eq!(
"%+f"
.parse::<CFormatSpec>()
.unwrap()
.format_float(f64::from(1.2345)),
"+1.234500".to_string()
);
assert_eq!(
"% f"
.parse::<CFormatSpec>()
.unwrap()
.format_float(f64::from(1.2345)),
" 1.234500".to_string()
);
assert_eq!(
"%f"
.parse::<CFormatSpec>()
.unwrap()
.format_float(f64::from(-1.2345)),
"-1.234500".to_string()
);
assert_eq!(
"%f"
.parse::<CFormatSpec>()
.unwrap()
.format_float(f64::from(1.2345678901)),
"1.234568".to_string()
);
}
#[test]

View File

@@ -29,6 +29,7 @@ use crate::vm::VirtualMachine;
use super::objbytes::PyBytes;
use super::objdict::PyDict;
use super::objint::{self, PyInt};
use super::objfloat;
use super::objiter;
use super::objnone::PyNone;
use super::objsequence::PySliceableSequence;
@@ -1220,6 +1221,18 @@ fn do_cformat_specifier(
}
Ok(format_spec.format_number(objint::get_value(&obj)))
}
CFormatType::Float(_) => {
if !objtype::isinstance(&obj, &vm.ctx.float_type()) {
let required_type_string = "an floating point";
return Err(vm.new_type_error(format!(
"%{} format: {} is required, not {}",
format_spec.format_char,
required_type_string,
obj.class()
)));
}
Ok(format_spec.format_float(objfloat::get_value(&obj)))
}
CFormatType::Character => {
let char_string = {
if objtype::isinstance(&obj, &vm.ctx.int_type()) {