diff --git a/src/libstd/fmt/mod.rs b/src/libstd/fmt/mod.rs index 411f9f25459..5b2a792a05b 100644 --- a/src/libstd/fmt/mod.rs +++ b/src/libstd/fmt/mod.rs @@ -147,6 +147,8 @@ The current mapping of types to traits is: * `p` ⇒ `Pointer` * `t` ⇒ `Binary` * `f` ⇒ `Float` +* `e` ⇒ `LowerExp` +* `E` ⇒ `UpperExp` * *nothing* ⇒ `Default` What this means is that any type of argument which implements the @@ -578,6 +580,12 @@ pub trait Pointer { fn fmt(&Self, &mut Formatter); } /// Format trait for the `f` character #[allow(missing_doc)] pub trait Float { fn fmt(&Self, &mut Formatter); } +/// Format trait for the `e` character +#[allow(missing_doc)] +pub trait LowerExp { fn fmt(&Self, &mut Formatter); } +/// Format trait for the `E` character +#[allow(missing_doc)] +pub trait UpperExp { fn fmt(&Self, &mut Formatter); } /// The `write` function takes an output stream, a precompiled format string, /// and a list of arguments. The arguments will be formatted according to the @@ -1085,6 +1093,28 @@ macro_rules! floating(($ty:ident) => { fmt.pad_integral(s.as_bytes(), "", *f >= 0.0); } } + + impl LowerExp for $ty { + fn fmt(f: &$ty, fmt: &mut Formatter) { + // XXX: this shouldn't perform an allocation + let s = match fmt.precision { + Some(i) => ::$ty::to_str_exp_exact(f.abs(), i, false), + None => ::$ty::to_str_exp_digits(f.abs(), 6, false) + }; + fmt.pad_integral(s.as_bytes(), "", *f >= 0.0); + } + } + + impl UpperExp for $ty { + fn fmt(f: &$ty, fmt: &mut Formatter) { + // XXX: this shouldn't perform an allocation + let s = match fmt.precision { + Some(i) => ::$ty::to_str_exp_exact(f.abs(), i, true), + None => ::$ty::to_str_exp_digits(f.abs(), 6, true) + }; + fmt.pad_integral(s.as_bytes(), "", *f >= 0.0); + } + } }) floating!(f32) floating!(f64) diff --git a/src/libstd/num/f32.rs b/src/libstd/num/f32.rs index e95ad7ca7f5..5df4b598a88 100644 --- a/src/libstd/num/f32.rs +++ b/src/libstd/num/f32.rs @@ -783,6 +783,40 @@ pub fn to_str_digits(num: f32, dig: uint) -> ~str { r } +/// +/// Converts a float to a string using the exponential notation with exactly the number of +/// provided digits after the decimal point in the significand +/// +/// # Arguments +/// +/// * num - The float value +/// * digits - The number of digits after the decimal point +/// * upper - Use `E` instead of `e` for the exponent sign +/// +#[inline] +pub fn to_str_exp_exact(num: f32, dig: uint, upper: bool) -> ~str { + let (r, _) = strconv::float_to_str_common( + num, 10u, true, strconv::SignNeg, strconv::DigExact(dig), strconv::ExpDec, upper); + r +} + +/// +/// Converts a float to a string using the exponential notation with the maximum number of +/// digits after the decimal point in the significand +/// +/// # Arguments +/// +/// * num - The float value +/// * digits - The number of digits after the decimal point +/// * upper - Use `E` instead of `e` for the exponent sign +/// +#[inline] +pub fn to_str_exp_digits(num: f32, dig: uint, upper: bool) -> ~str { + let (r, _) = strconv::float_to_str_common( + num, 10u, true, strconv::SignNeg, strconv::DigMax(dig), strconv::ExpDec, upper); + r +} + impl to_str::ToStr for f32 { #[inline] fn to_str(&self) -> ~str { to_str_digits(*self, 8) } diff --git a/src/libstd/num/f64.rs b/src/libstd/num/f64.rs index 33ee4acf58b..6c0a2a41ec1 100644 --- a/src/libstd/num/f64.rs +++ b/src/libstd/num/f64.rs @@ -785,6 +785,40 @@ pub fn to_str_digits(num: f64, dig: uint) -> ~str { r } +/// +/// Converts a float to a string using the exponential notation with exactly the number of +/// provided digits after the decimal point in the significand +/// +/// # Arguments +/// +/// * num - The float value +/// * digits - The number of digits after the decimal point +/// * upper - Use `E` instead of `e` for the exponent sign +/// +#[inline] +pub fn to_str_exp_exact(num: f64, dig: uint, upper: bool) -> ~str { + let (r, _) = strconv::float_to_str_common( + num, 10u, true, strconv::SignNeg, strconv::DigExact(dig), strconv::ExpDec, upper); + r +} + +/// +/// Converts a float to a string using the exponential notation with the maximum number of +/// digits after the decimal point in the significand +/// +/// # Arguments +/// +/// * num - The float value +/// * digits - The number of digits after the decimal point +/// * upper - Use `E` instead of `e` for the exponent sign +/// +#[inline] +pub fn to_str_exp_digits(num: f64, dig: uint, upper: bool) -> ~str { + let (r, _) = strconv::float_to_str_common( + num, 10u, true, strconv::SignNeg, strconv::DigMax(dig), strconv::ExpDec, upper); + r +} + impl to_str::ToStr for f64 { #[inline] fn to_str(&self) -> ~str { to_str_digits(*self, 8) } diff --git a/src/libsyntax/ext/format.rs b/src/libsyntax/ext/format.rs index 8e7947a3d31..bbf6f7fff7f 100644 --- a/src/libsyntax/ext/format.rs +++ b/src/libsyntax/ext/format.rs @@ -687,6 +687,8 @@ impl<'a> Context<'a> { "b" => "Bool", "c" => "Char", "d" | "i" => "Signed", + "e" => "LowerExp", + "E" => "UpperExp", "f" => "Float", "o" => "Octal", "p" => "Pointer",