diff --git a/src/libstd/fmt/mod.rs b/src/libstd/fmt/mod.rs index 411f9f254593f..5b2a792a05b10 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 5b0c75ef17493..0af8f155c6878 100644 --- a/src/libstd/num/f32.rs +++ b/src/libstd/num/f32.rs @@ -285,20 +285,16 @@ impl Signed for f32 { #[inline] fn abs(&self) -> f32 { abs(*self) } - /// /// The positive difference of two numbers. Returns `0.0` if the number is less than or /// equal to `other`, otherwise the difference between`self` and `other` is returned. - /// #[inline] fn abs_sub(&self, other: &f32) -> f32 { abs_sub(*self, *other) } - /// /// # Returns /// /// - `1.0` if the number is positive, `+0.0` or `INFINITY` /// - `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY` /// - `NAN` if the number is NaN - /// #[inline] fn signum(&self) -> f32 { if self.is_nan() { NAN } else { copysign(1.0, *self) } @@ -330,14 +326,12 @@ impl Round for f32 { #[inline] fn trunc(&self) -> f32 { trunc(*self) } - /// /// The fractional part of the number, satisfying: /// /// ```rust /// let x = 1.65f32; /// assert!(x == x.trunc() + x.fract()) /// ``` - /// #[inline] fn fract(&self) -> f32 { *self - self.trunc() } } @@ -490,7 +484,6 @@ impl Real for f32 { #[inline] fn tanh(&self) -> f32 { tanh(*self) } - /// /// Inverse hyperbolic sine /// /// # Returns @@ -498,7 +491,6 @@ impl Real for f32 { /// - on success, the inverse hyperbolic sine of `self` will be returned /// - `self` if `self` is `0.0`, `-0.0`, `INFINITY`, or `NEG_INFINITY` /// - `NAN` if `self` is `NAN` - /// #[inline] fn asinh(&self) -> f32 { match *self { @@ -507,7 +499,6 @@ impl Real for f32 { } } - /// /// Inverse hyperbolic cosine /// /// # Returns @@ -515,7 +506,6 @@ impl Real for f32 { /// - on success, the inverse hyperbolic cosine of `self` will be returned /// - `INFINITY` if `self` is `INFINITY` /// - `NAN` if `self` is `NAN` or `self < 1.0` (including `NEG_INFINITY`) - /// #[inline] fn acosh(&self) -> f32 { match *self { @@ -524,7 +514,6 @@ impl Real for f32 { } } - /// /// Inverse hyperbolic tangent /// /// # Returns @@ -535,7 +524,6 @@ impl Real for f32 { /// - `NEG_INFINITY` if `self` is `-1.0` /// - `NAN` if the `self` is `NAN` or outside the domain of `-1.0 <= self <= 1.0` /// (including `INFINITY` and `NEG_INFINITY`) - /// #[inline] fn atanh(&self) -> f32 { 0.5 * ((2.0 * *self) / (1.0 - *self)).ln_1p() @@ -643,12 +631,10 @@ impl Float for f32 { ldexp(x, exp as c_int) } - /// /// Breaks the number into a normalized fraction and a base-2 exponent, satisfying: /// /// - `self = x * pow(2, exp)` /// - `0.5 <= abs(x) < 1.0` - /// #[inline] fn frexp(&self) -> (f32, int) { let mut exp = 0; @@ -656,25 +642,19 @@ impl Float for f32 { (x, exp as int) } - /// /// Returns the exponential of the number, minus `1`, in a way that is accurate /// even if the number is close to zero - /// #[inline] fn exp_m1(&self) -> f32 { exp_m1(*self) } - /// /// Returns the natural logarithm of the number plus `1` (`ln(1+n)`) more accurately /// than if the operations were performed separately - /// #[inline] fn ln_1p(&self) -> f32 { ln_1p(*self) } - /// /// Fused multiply-add. Computes `(self * a) + b` with only one rounding error. This /// produces a more accurate result with better performance than a separate multiplication /// operation followed by an add. - /// #[inline] fn mul_add(&self, a: f32, b: f32) -> f32 { mul_add(*self, a, b) @@ -708,35 +688,30 @@ impl Float for f32 { // Section: String Conversions // -/// /// Converts a float to a string /// /// # Arguments /// /// * num - The float value -/// #[inline] pub fn to_str(num: f32) -> ~str { let (r, _) = strconv::float_to_str_common( - num, 10u, true, strconv::SignNeg, strconv::DigAll); + num, 10u, true, strconv::SignNeg, strconv::DigAll, strconv::ExpNone, false); r } -/// /// Converts a float to a string in hexadecimal format /// /// # Arguments /// /// * num - The float value -/// #[inline] pub fn to_str_hex(num: f32) -> ~str { let (r, _) = strconv::float_to_str_common( - num, 16u, true, strconv::SignNeg, strconv::DigAll); + num, 16u, true, strconv::SignNeg, strconv::DigAll, strconv::ExpNone, false); r } -/// /// Converts a float to a string in a given radix, and a flag indicating /// whether it's a special value /// @@ -744,14 +719,12 @@ pub fn to_str_hex(num: f32) -> ~str { /// /// * num - The float value /// * radix - The base to use -/// #[inline] pub fn to_str_radix_special(num: f32, rdx: uint) -> (~str, bool) { strconv::float_to_str_common(num, rdx, true, - strconv::SignNeg, strconv::DigAll) + strconv::SignNeg, strconv::DigAll, strconv::ExpNone, false) } -/// /// Converts a float to a string with exactly the number of /// provided significant digits /// @@ -759,15 +732,13 @@ pub fn to_str_radix_special(num: f32, rdx: uint) -> (~str, bool) { /// /// * num - The float value /// * digits - The number of significant digits -/// #[inline] pub fn to_str_exact(num: f32, dig: uint) -> ~str { let (r, _) = strconv::float_to_str_common( - num, 10u, true, strconv::SignNeg, strconv::DigExact(dig)); + num, 10u, true, strconv::SignNeg, strconv::DigExact(dig), strconv::ExpNone, false); r } -/// /// Converts a float to a string with a maximum number of /// significant digits /// @@ -775,11 +746,40 @@ pub fn to_str_exact(num: f32, dig: uint) -> ~str { /// /// * num - The float value /// * digits - The number of significant digits -/// #[inline] pub fn to_str_digits(num: f32, dig: uint) -> ~str { let (r, _) = strconv::float_to_str_common( - num, 10u, true, strconv::SignNeg, strconv::DigMax(dig)); + num, 10u, true, strconv::SignNeg, strconv::DigMax(dig), strconv::ExpNone, false); + 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 } @@ -804,14 +804,13 @@ impl num::ToStrRadix for f32 { #[inline] fn to_str_radix(&self, rdx: uint) -> ~str { let (r, special) = strconv::float_to_str_common( - *self, rdx, true, strconv::SignNeg, strconv::DigAll); + *self, rdx, true, strconv::SignNeg, strconv::DigAll, strconv::ExpNone, false); if special { fail!("number has a special value, \ try to_str_radix_special() if those are expected") } r } } -/// /// Convert a string in base 16 to a float. /// Accepts a optional binary exponent. /// @@ -837,7 +836,6 @@ impl num::ToStrRadix for f32 { /// /// `None` if the string did not represent a valid number. Otherwise, /// `Some(n)` where `n` is the floating-point number represented by `[num]`. -/// #[inline] pub fn from_str_hex(num: &str) -> Option { strconv::from_str_common(num, 16u, true, true, true, @@ -845,7 +843,6 @@ pub fn from_str_hex(num: &str) -> Option { } impl FromStr for f32 { - /// /// Convert a string in base 10 to a float. /// Accepts a optional decimal exponent. /// @@ -871,7 +868,6 @@ impl FromStr for f32 { /// /// `None` if the string did not represent a valid number. Otherwise, /// `Some(n)` where `n` is the floating-point number represented by `num`. - /// #[inline] fn from_str(val: &str) -> Option { strconv::from_str_common(val, 10u, true, true, true, @@ -880,7 +876,6 @@ impl FromStr for f32 { } impl num::FromStrRadix for f32 { - /// /// Convert a string in an given base to a float. /// /// Due to possible conflicts, this function does **not** accept @@ -898,7 +893,6 @@ impl num::FromStrRadix for f32 { /// /// `None` if the string did not represent a valid number. Otherwise, /// `Some(n)` where `n` is the floating-point number represented by `num`. - /// #[inline] fn from_str_radix(val: &str, rdx: uint) -> Option { strconv::from_str_common(val, rdx, true, true, false, diff --git a/src/libstd/num/f64.rs b/src/libstd/num/f64.rs index 95e5797ae9356..1155a89876e5a 100644 --- a/src/libstd/num/f64.rs +++ b/src/libstd/num/f64.rs @@ -287,20 +287,16 @@ impl Signed for f64 { #[inline] fn abs(&self) -> f64 { abs(*self) } - /// /// The positive difference of two numbers. Returns `0.0` if the number is less than or /// equal to `other`, otherwise the difference between`self` and `other` is returned. - /// #[inline] fn abs_sub(&self, other: &f64) -> f64 { abs_sub(*self, *other) } - /// /// # Returns /// /// - `1.0` if the number is positive, `+0.0` or `INFINITY` /// - `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY` /// - `NAN` if the number is NaN - /// #[inline] fn signum(&self) -> f64 { if self.is_nan() { NAN } else { copysign(1.0, *self) } @@ -332,14 +328,12 @@ impl Round for f64 { #[inline] fn trunc(&self) -> f64 { trunc(*self) } - /// /// The fractional part of the number, satisfying: /// /// ```rust /// let x = 1.65f64; /// assert!(x == x.trunc() + x.fract()) /// ``` - /// #[inline] fn fract(&self) -> f64 { *self - self.trunc() } } @@ -492,7 +486,6 @@ impl Real for f64 { #[inline] fn tanh(&self) -> f64 { tanh(*self) } - /// /// Inverse hyperbolic sine /// /// # Returns @@ -500,7 +493,6 @@ impl Real for f64 { /// - on success, the inverse hyperbolic sine of `self` will be returned /// - `self` if `self` is `0.0`, `-0.0`, `INFINITY`, or `NEG_INFINITY` /// - `NAN` if `self` is `NAN` - /// #[inline] fn asinh(&self) -> f64 { match *self { @@ -509,7 +501,6 @@ impl Real for f64 { } } - /// /// Inverse hyperbolic cosine /// /// # Returns @@ -517,7 +508,6 @@ impl Real for f64 { /// - on success, the inverse hyperbolic cosine of `self` will be returned /// - `INFINITY` if `self` is `INFINITY` /// - `NAN` if `self` is `NAN` or `self < 1.0` (including `NEG_INFINITY`) - /// #[inline] fn acosh(&self) -> f64 { match *self { @@ -526,7 +516,6 @@ impl Real for f64 { } } - /// /// Inverse hyperbolic tangent /// /// # Returns @@ -537,7 +526,6 @@ impl Real for f64 { /// - `NEG_INFINITY` if `self` is `-1.0` /// - `NAN` if the `self` is `NAN` or outside the domain of `-1.0 <= self <= 1.0` /// (including `INFINITY` and `NEG_INFINITY`) - /// #[inline] fn atanh(&self) -> f64 { 0.5 * ((2.0 * *self) / (1.0 - *self)).ln_1p() @@ -645,12 +633,10 @@ impl Float for f64 { ldexp(x, exp as c_int) } - /// /// Breaks the number into a normalized fraction and a base-2 exponent, satisfying: /// /// - `self = x * pow(2, exp)` /// - `0.5 <= abs(x) < 1.0` - /// #[inline] fn frexp(&self) -> (f64, int) { let mut exp = 0; @@ -658,25 +644,19 @@ impl Float for f64 { (x, exp as int) } - /// /// Returns the exponential of the number, minus `1`, in a way that is accurate /// even if the number is close to zero - /// #[inline] fn exp_m1(&self) -> f64 { exp_m1(*self) } - /// /// Returns the natural logarithm of the number plus `1` (`ln(1+n)`) more accurately /// than if the operations were performed separately - /// #[inline] fn ln_1p(&self) -> f64 { ln_1p(*self) } - /// /// Fused multiply-add. Computes `(self * a) + b` with only one rounding error. This /// produces a more accurate result with better performance than a separate multiplication /// operation followed by an add. - /// #[inline] fn mul_add(&self, a: f64, b: f64) -> f64 { mul_add(*self, a, b) @@ -710,35 +690,30 @@ impl Float for f64 { // Section: String Conversions // -/// /// Converts a float to a string /// /// # Arguments /// /// * num - The float value -/// #[inline] pub fn to_str(num: f64) -> ~str { let (r, _) = strconv::float_to_str_common( - num, 10u, true, strconv::SignNeg, strconv::DigAll); + num, 10u, true, strconv::SignNeg, strconv::DigAll, strconv::ExpNone, false); r } -/// /// Converts a float to a string in hexadecimal format /// /// # Arguments /// /// * num - The float value -/// #[inline] pub fn to_str_hex(num: f64) -> ~str { let (r, _) = strconv::float_to_str_common( - num, 16u, true, strconv::SignNeg, strconv::DigAll); + num, 16u, true, strconv::SignNeg, strconv::DigAll, strconv::ExpNone, false); r } -/// /// Converts a float to a string in a given radix, and a flag indicating /// whether it's a special value /// @@ -746,14 +721,12 @@ pub fn to_str_hex(num: f64) -> ~str { /// /// * num - The float value /// * radix - The base to use -/// #[inline] pub fn to_str_radix_special(num: f64, rdx: uint) -> (~str, bool) { strconv::float_to_str_common(num, rdx, true, - strconv::SignNeg, strconv::DigAll) + strconv::SignNeg, strconv::DigAll, strconv::ExpNone, false) } -/// /// Converts a float to a string with exactly the number of /// provided significant digits /// @@ -761,15 +734,13 @@ pub fn to_str_radix_special(num: f64, rdx: uint) -> (~str, bool) { /// /// * num - The float value /// * digits - The number of significant digits -/// #[inline] pub fn to_str_exact(num: f64, dig: uint) -> ~str { let (r, _) = strconv::float_to_str_common( - num, 10u, true, strconv::SignNeg, strconv::DigExact(dig)); + num, 10u, true, strconv::SignNeg, strconv::DigExact(dig), strconv::ExpNone, false); r } -/// /// Converts a float to a string with a maximum number of /// significant digits /// @@ -777,11 +748,40 @@ pub fn to_str_exact(num: f64, dig: uint) -> ~str { /// /// * num - The float value /// * digits - The number of significant digits -/// #[inline] pub fn to_str_digits(num: f64, dig: uint) -> ~str { let (r, _) = strconv::float_to_str_common( - num, 10u, true, strconv::SignNeg, strconv::DigMax(dig)); + num, 10u, true, strconv::SignNeg, strconv::DigMax(dig), strconv::ExpNone, false); + 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 } @@ -806,14 +806,13 @@ impl num::ToStrRadix for f64 { #[inline] fn to_str_radix(&self, rdx: uint) -> ~str { let (r, special) = strconv::float_to_str_common( - *self, rdx, true, strconv::SignNeg, strconv::DigAll); + *self, rdx, true, strconv::SignNeg, strconv::DigAll, strconv::ExpNone, false); if special { fail!("number has a special value, \ try to_str_radix_special() if those are expected") } r } } -/// /// Convert a string in base 16 to a float. /// Accepts a optional binary exponent. /// @@ -839,7 +838,6 @@ impl num::ToStrRadix for f64 { /// /// `None` if the string did not represent a valid number. Otherwise, /// `Some(n)` where `n` is the floating-point number represented by `[num]`. -/// #[inline] pub fn from_str_hex(num: &str) -> Option { strconv::from_str_common(num, 16u, true, true, true, @@ -847,7 +845,6 @@ pub fn from_str_hex(num: &str) -> Option { } impl FromStr for f64 { - /// /// Convert a string in base 10 to a float. /// Accepts a optional decimal exponent. /// @@ -873,7 +870,6 @@ impl FromStr for f64 { /// /// `none` if the string did not represent a valid number. Otherwise, /// `Some(n)` where `n` is the floating-point number represented by `num`. - /// #[inline] fn from_str(val: &str) -> Option { strconv::from_str_common(val, 10u, true, true, true, @@ -882,7 +878,6 @@ impl FromStr for f64 { } impl num::FromStrRadix for f64 { - /// /// Convert a string in an given base to a float. /// /// Due to possible conflicts, this function does **not** accept @@ -900,7 +895,6 @@ impl num::FromStrRadix for f64 { /// /// `None` if the string did not represent a valid number. Otherwise, /// `Some(n)` where `n` is the floating-point number represented by `num`. - /// #[inline] fn from_str_radix(val: &str, rdx: uint) -> Option { strconv::from_str_common(val, rdx, true, true, false, diff --git a/src/libstd/num/strconv.rs b/src/libstd/num/strconv.rs index bf9e6b739f2a4..30abe86866e22 100644 --- a/src/libstd/num/strconv.rs +++ b/src/libstd/num/strconv.rs @@ -207,11 +207,13 @@ pub fn int_to_str_bytes_common 36. + * - Fails if `radix` > 14 and `exp_format` is `ExpDec` due to conflict + * between digit and exponent sign `'e'`. + * - Fails if `radix` > 25 and `exp_format` is `ExpBin` due to conflict + * between digit and exponent sign `'p'`. */ pub fn float_to_str_bytes_common+Neg+Rem+Mul>( num: T, radix: uint, negative_zero: bool, - sign: SignFormat, digits: SignificantDigits) -> (~[u8], bool) { + sign: SignFormat, digits: SignificantDigits, exp_format: ExponentFormat, exp_upper: bool + ) -> (~[u8], bool) { assert!(2 <= radix && radix <= 36); + match exp_format { + ExpDec if radix >= DIGIT_E_RADIX // decimal exponent 'e' + => fail!("float_to_str_bytes_common: radix {} incompatible with \ + use of 'e' as decimal exponent", radix), + ExpBin if radix >= DIGIT_P_RADIX // binary exponent 'p' + => fail!("float_to_str_bytes_common: radix {} incompatible with \ + use of 'p' as binary exponent", radix), + _ => () + } let _0: T = Zero::zero(); let _1: T = One::one(); @@ -260,6 +287,23 @@ pub fn float_to_str_bytes_common (num, 0i32), + ExpDec | ExpBin => { + if num == _0 { + (num, 0i32) + } else { + let (exp, exp_base) = match exp_format { + ExpDec => (num.abs().log10().floor(), cast::(10.0f64).unwrap()), + ExpBin => (num.abs().log2().floor(), cast::(2.0f64).unwrap()), + ExpNone => unreachable!() + }; + + (num / exp_base.powf(&exp), cast::(exp).unwrap()) + } + } + }; + // First emit the non-fractional part, looping at least once to make // sure at least a `0` gets emitted. let mut deccum = num.trunc(); @@ -413,6 +457,21 @@ pub fn float_to_str_bytes_common (), + _ => { + buf.push(match exp_format { + ExpDec if exp_upper => 'E', + ExpDec if !exp_upper => 'e', + ExpBin if exp_upper => 'P', + ExpBin if !exp_upper => 'p', + _ => unreachable!() + } as u8); + + int_to_str_bytes_common(exp, 10, sign, |c| buf.push(c)); + } + } + (buf, false) } @@ -424,9 +483,10 @@ pub fn float_to_str_bytes_common+Neg+Rem+Mul>( num: T, radix: uint, negative_zero: bool, - sign: SignFormat, digits: SignificantDigits) -> (~str, bool) { + sign: SignFormat, digits: SignificantDigits, exp_format: ExponentFormat, exp_capital: bool + ) -> (~str, bool) { let (bytes, special) = float_to_str_bytes_common(num, radix, - negative_zero, sign, digits); + negative_zero, sign, digits, exp_format, exp_capital); (str::from_utf8_owned(bytes).unwrap(), special) } diff --git a/src/libsyntax/ext/format.rs b/src/libsyntax/ext/format.rs index 8e7947a3d31a9..bbf6f7fff7f9e 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", diff --git a/src/test/run-pass/exponential-notation.rs b/src/test/run-pass/exponential-notation.rs new file mode 100644 index 0000000000000..254c093e703a3 --- /dev/null +++ b/src/test/run-pass/exponential-notation.rs @@ -0,0 +1,34 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#[feature(macro_rules)]; + +use s = std::num::strconv; +use to_str = std::num::strconv::float_to_str_common; + +macro_rules! t(($a:expr, $b:expr) => { { let (r, _) = $a; assert_eq!(r, $b.to_owned()) } }) + +pub fn main() { + // Basic usage + t!(to_str(1.2345678e-5, 10u, true, s::SignNeg, s::DigMax(6), s::ExpDec, false), + "1.234568e-5") + + // Hexadecimal output + t!(to_str(7.281738281250e+01, 16u, true, s::SignAll, s::DigMax(6), s::ExpBin, false), + "+1.2345p+6") + t!(to_str(-1.777768135071e-02, 16u, true, s::SignAll, s::DigMax(6), s::ExpBin, false), + "-1.2345p-6") + + // Some denormals + t!(to_str(4.9406564584124654e-324, 10u, true, s::SignNeg, s::DigMax(6), s::ExpBin, false), + "1p-1074") + t!(to_str(2.2250738585072009e-308, 10u, true, s::SignNeg, s::DigMax(6), s::ExpBin, false), + "1p-1022") +} diff --git a/src/test/run-pass/ifmt.rs b/src/test/run-pass/ifmt.rs index 76759d04ab4ae..610cba1eb1fa6 100644 --- a/src/test/run-pass/ifmt.rs +++ b/src/test/run-pass/ifmt.rs @@ -1,4 +1,4 @@ -// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -219,6 +219,14 @@ pub fn main() { t!(format!("{:+10.3f}", 1.0f64), " +1.000"); t!(format!("{:+10.3f}", -1.0f64), " -1.000"); + t!(format!("{:e}", 1.2345e6f32), "1.2345e6"); + t!(format!("{:e}", 1.2345e6f64), "1.2345e6"); + t!(format!("{:E}", 1.2345e6f64), "1.2345E6"); + t!(format!("{:.3e}", 1.2345e6f64), "1.234e6"); + t!(format!("{:10.3e}", 1.2345e6f64), " 1.234e6"); + t!(format!("{:+10.3e}", 1.2345e6f64), " +1.234e6"); + t!(format!("{:+10.3e}", -1.2345e6f64), " -1.234e6"); + // Escaping t!(format!("\\{"), "{"); t!(format!("\\}"), "}");