From f138f3da9ebd70ce743e6490270e3dce8198275c Mon Sep 17 00:00:00 2001 From: Sigurd Kolltveit Date: Fri, 26 Feb 2016 16:51:05 +0100 Subject: [PATCH 1/6] Add formatting options for Complex --- complex/src/lib.rs | 49 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 46 insertions(+), 3 deletions(-) diff --git a/complex/src/lib.rs b/complex/src/lib.rs index 62f74cc..f942b82 100644 --- a/complex/src/lib.rs +++ b/complex/src/lib.rs @@ -616,15 +616,49 @@ impl One for Complex { } } +macro_rules! write_complex { + ($f:ident, $re_fmt:expr, $im_fmt:expr, $re:expr, $im:expr, $( $arg:expr ),*) => { + if $im < Zero::zero() { + write!($f, concat!($re_fmt, "-", $im_fmt), $re, T::zero() - $im.clone(), $( $arg, )*) + } else { + write!($f, concat!($re_fmt, "+", $im_fmt), $re, $im, $( $arg, )*) + } + } +} + /* string conversions */ impl fmt::Display for Complex where T: fmt::Display + Num + PartialOrd + Clone { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - if self.im < Zero::zero() { - write!(f, "{}-{}i", self.re, T::zero() - self.im.clone()) + if let Some(precision) = f.precision() { + write_complex!(f, "{0:.2$}", "{1:.2$}i", self.re, self.im, precision) } else { - write!(f, "{}+{}i", self.re, self.im) + write_complex!(f, "{0}", "{1}i", self.re, self.im,) + } + } +} + +impl fmt::LowerExp for Complex where + T: fmt::LowerExp + Num + PartialOrd + Clone +{ + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + if let Some(precision) = f.precision() { + write_complex!(f, "{0:.2$e}", "{1:.2$e}i", self.re, self.im, precision) + } else { + write_complex!(f, "{0:e}", "{1:e}i", self.re, self.im,) + } + } +} + +impl fmt::UpperExp for Complex where + T: fmt::UpperExp + Num + PartialOrd + Clone +{ + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + if let Some(precision) = f.precision() { + write_complex!(f, "{0:.2$E}", "{1:.2$E}i", self.re, self.im, precision) + } else { + write_complex!(f, "{0:E}", "{1:E}i", self.re, self.im,) } } } @@ -1210,6 +1244,15 @@ mod test { test(_05_05i, "0.5+0.5i".to_string()); } + #[test] + fn test_string_formatting() { + let a: Complex64 = Complex::new(1.234567, 123.4567); + assert_eq!(format!("{}", a), "1.234567+123.4567i"); + assert_eq!(format!("{:.2}", a), "1.23+123.46i"); + assert_eq!(format!("{:.2E}", a), "1.23E0+1.23E2i"); + assert_eq!(format!("{:e}", a), "1.234567e0+1.234567e2i"); + } + #[test] fn test_hash() { let a = Complex::new(0i32, 0i32); From 6113192e04ee28aa92fa7b7637bf6bccc056b54c Mon Sep 17 00:00:00 2001 From: Sigurd Kolltveit Date: Wed, 15 Feb 2017 19:40:38 +0100 Subject: [PATCH 2/6] Add tests for more formatting options --- complex/src/lib.rs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/complex/src/lib.rs b/complex/src/lib.rs index f942b82..264e353 100644 --- a/complex/src/lib.rs +++ b/complex/src/lib.rs @@ -1246,11 +1246,18 @@ mod test { #[test] fn test_string_formatting() { - let a: Complex64 = Complex::new(1.234567, 123.4567); - assert_eq!(format!("{}", a), "1.234567+123.4567i"); + let a = Complex::new(1.23456, 123.456); + assert_eq!(format!("{}", a), "1.23456+123.456i"); assert_eq!(format!("{:.2}", a), "1.23+123.46i"); assert_eq!(format!("{:.2E}", a), "1.23E0+1.23E2i"); - assert_eq!(format!("{:e}", a), "1.234567e0+1.234567e2i"); + assert_eq!(format!("{:.2e}", a), "1.23e0+1.23e2i"); + + let b = Complex::new(128, 255); + assert_eq!(format!("{:X}", b), "80+FFi"); + assert_eq!(format!("{:#x}", b), "0x80+0xffi"); + assert_eq!(format!("{:+#b}", b), "+0b1000000+0b1111111i"); + assert_eq!(format!("{:+#16o}", b), " +0o200+0o377i"); + assert_eq!(format!("{:+#016x}", b), "+0x00080+0x00ffi"); } #[test] From e2759e03217e723c7939b2d2839208b028e885a1 Mon Sep 17 00:00:00 2001 From: Sigurd Kolltveit Date: Sat, 18 Mar 2017 15:50:39 +0100 Subject: [PATCH 3/6] Implement more formatting options for Complex --- complex/src/lib.rs | 107 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 86 insertions(+), 21 deletions(-) diff --git a/complex/src/lib.rs b/complex/src/lib.rs index 264e353..e4e8c66 100644 --- a/complex/src/lib.rs +++ b/complex/src/lib.rs @@ -617,13 +617,58 @@ impl One for Complex { } macro_rules! write_complex { - ($f:ident, $re_fmt:expr, $im_fmt:expr, $re:expr, $im:expr, $( $arg:expr ),*) => { - if $im < Zero::zero() { - write!($f, concat!($re_fmt, "-", $im_fmt), $re, T::zero() - $im.clone(), $( $arg, )*) - } else { - write!($f, concat!($re_fmt, "+", $im_fmt), $re, $im, $( $arg, )*) + ($f:ident, $t:expr, $prefix:expr, $re:expr, $im:expr, $T:ident) => {{ + let zero: $T = Zero::zero(); + let abs_re = if $re < Zero::zero() { zero.clone() - $re.clone() } else { $re.clone() }; + let abs_im = if $im < Zero::zero() { zero.clone() - $im.clone() } else { $im.clone() }; + + let mut real: String; + let mut imag: String; + + if let Some(prec) = $f.precision() { + real = format!(concat!("{:.1$", $t, "}"), abs_re, prec); + imag = format!(concat!("{:.1$", $t, "}"), abs_im, prec); } - } + else { + real = format!(concat!("{:", $t, "}"), abs_re); + imag = format!(concat!("{:", $t, "}"), abs_im); + } + + let prefix = if $f.alternate() { $prefix } else { "" }; + let sign = if $re < Zero::zero() { + "-" + } else if $f.sign_plus() { + "+" + } else { + "" + }; + + if $f.sign_aware_zero_pad() && $f.width().is_some() { + let total_width = $f.width().unwrap(); + // Subtract leading sign, two prefixes, middle operator and trailing 'i' + // to obtain the width scalars need to be padded to + let subtract = sign.len() + prefix.len()*2 + 1 + 1; + let scalar_width = total_width - subtract; + let real_width = scalar_width - (scalar_width/2); + let imag_width = scalar_width/2; + real = format!("{0:0>1$}", real, real_width); + imag = format!("{0:0>1$}", imag, imag_width); + } + + let complex = if $im < Zero::zero() { + format!("{}{pre}{re}-{pre}{im}i", sign, re=real, im=imag, pre=prefix) + } + else { + format!("{}{pre}{re}+{pre}{im}i", sign, re=real, im=imag, pre=prefix) + }; + + if let Some(width) = $f.width() { + write!($f, "{0: >1$}", complex, width) + } + else { + write!($f, "{}", complex) + } + }} } /* string conversions */ @@ -631,11 +676,7 @@ impl fmt::Display for Complex where T: fmt::Display + Num + PartialOrd + Clone { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - if let Some(precision) = f.precision() { - write_complex!(f, "{0:.2$}", "{1:.2$}i", self.re, self.im, precision) - } else { - write_complex!(f, "{0}", "{1}i", self.re, self.im,) - } + write_complex!(f, "", "", self.re, self.im, T) } } @@ -643,11 +684,7 @@ impl fmt::LowerExp for Complex where T: fmt::LowerExp + Num + PartialOrd + Clone { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - if let Some(precision) = f.precision() { - write_complex!(f, "{0:.2$e}", "{1:.2$e}i", self.re, self.im, precision) - } else { - write_complex!(f, "{0:e}", "{1:e}i", self.re, self.im,) - } + write_complex!(f, "e", "", self.re, self.im, T) } } @@ -655,11 +692,39 @@ impl fmt::UpperExp for Complex where T: fmt::UpperExp + Num + PartialOrd + Clone { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - if let Some(precision) = f.precision() { - write_complex!(f, "{0:.2$E}", "{1:.2$E}i", self.re, self.im, precision) - } else { - write_complex!(f, "{0:E}", "{1:E}i", self.re, self.im,) - } + write_complex!(f, "E", "", self.re, self.im, T) + } +} + +impl fmt::LowerHex for Complex where + T: fmt::LowerHex + Num + PartialOrd + Clone +{ + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write_complex!(f, "x", "0x", self.re, self.im, T) + } +} + +impl fmt::UpperHex for Complex where + T: fmt::UpperHex + Num + PartialOrd + Clone +{ + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write_complex!(f, "X", "0x", self.re, self.im, T) + } +} + +impl fmt::Octal for Complex where + T: fmt::Octal + Num + PartialOrd + Clone +{ + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write_complex!(f, "o", "0o", self.re, self.im, T) + } +} + +impl fmt::Binary for Complex where + T: fmt::Binary + Num + PartialOrd + Clone +{ + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write_complex!(f, "b", "0b", self.re, self.im, T) } } From 69943915ba0da48eeee7dd9b208541a672a88fc0 Mon Sep 17 00:00:00 2001 From: Sigurd Kolltveit Date: Sat, 18 Mar 2017 15:53:36 +0100 Subject: [PATCH 4/6] Add more string formatting tests --- complex/src/lib.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/complex/src/lib.rs b/complex/src/lib.rs index e4e8c66..9d1cff8 100644 --- a/complex/src/lib.rs +++ b/complex/src/lib.rs @@ -1314,15 +1314,19 @@ mod test { let a = Complex::new(1.23456, 123.456); assert_eq!(format!("{}", a), "1.23456+123.456i"); assert_eq!(format!("{:.2}", a), "1.23+123.46i"); - assert_eq!(format!("{:.2E}", a), "1.23E0+1.23E2i"); assert_eq!(format!("{:.2e}", a), "1.23e0+1.23e2i"); + assert_eq!(format!("{:+020.2E}", a), "+0001.23E0+001.23E2i"); - let b = Complex::new(128, 255); + let b = Complex::new(0x80, 0xff); assert_eq!(format!("{:X}", b), "80+FFi"); assert_eq!(format!("{:#x}", b), "0x80+0xffi"); - assert_eq!(format!("{:+#b}", b), "+0b1000000+0b1111111i"); + assert_eq!(format!("{:+#b}", b), "+0b10000000+0b11111111i"); assert_eq!(format!("{:+#16o}", b), " +0o200+0o377i"); assert_eq!(format!("{:+#016x}", b), "+0x00080+0x00ffi"); + + let c = Complex::new(-10, -10000); + assert_eq!(format!("{}", c), "-10-10000i"); + assert_eq!(format!("{:016}", c), "-0000010-010000i"); } #[test] From e044cfbc6d1b346f23914b3ab4645be2d07c4433 Mon Sep 17 00:00:00 2001 From: Sigurd Kolltveit Date: Sat, 18 Mar 2017 17:22:58 +0100 Subject: [PATCH 5/6] Simplify some lines --- complex/src/lib.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/complex/src/lib.rs b/complex/src/lib.rs index 9d1cff8..5912400 100644 --- a/complex/src/lib.rs +++ b/complex/src/lib.rs @@ -618,9 +618,8 @@ impl One for Complex { macro_rules! write_complex { ($f:ident, $t:expr, $prefix:expr, $re:expr, $im:expr, $T:ident) => {{ - let zero: $T = Zero::zero(); - let abs_re = if $re < Zero::zero() { zero.clone() - $re.clone() } else { $re.clone() }; - let abs_im = if $im < Zero::zero() { zero.clone() - $im.clone() } else { $im.clone() }; + let abs_re = if $re < Zero::zero() { $T::zero() - $re.clone() } else { $re.clone() }; + let abs_im = if $im < Zero::zero() { $T::zero() - $im.clone() } else { $im.clone() }; let mut real: String; let mut imag: String; From 2784b89837600845a7d8a6947128cc6bd5a0933e Mon Sep 17 00:00:00 2001 From: Sigurd Kolltveit Date: Mon, 20 Mar 2017 19:04:17 +0100 Subject: [PATCH 6/6] Remove support for zero padding --- complex/src/lib.rs | 21 ++++----------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/complex/src/lib.rs b/complex/src/lib.rs index 5912400..1ef6e03 100644 --- a/complex/src/lib.rs +++ b/complex/src/lib.rs @@ -621,8 +621,8 @@ macro_rules! write_complex { let abs_re = if $re < Zero::zero() { $T::zero() - $re.clone() } else { $re.clone() }; let abs_im = if $im < Zero::zero() { $T::zero() - $im.clone() } else { $im.clone() }; - let mut real: String; - let mut imag: String; + let real: String; + let imag: String; if let Some(prec) = $f.precision() { real = format!(concat!("{:.1$", $t, "}"), abs_re, prec); @@ -642,18 +642,6 @@ macro_rules! write_complex { "" }; - if $f.sign_aware_zero_pad() && $f.width().is_some() { - let total_width = $f.width().unwrap(); - // Subtract leading sign, two prefixes, middle operator and trailing 'i' - // to obtain the width scalars need to be padded to - let subtract = sign.len() + prefix.len()*2 + 1 + 1; - let scalar_width = total_width - subtract; - let real_width = scalar_width - (scalar_width/2); - let imag_width = scalar_width/2; - real = format!("{0:0>1$}", real, real_width); - imag = format!("{0:0>1$}", imag, imag_width); - } - let complex = if $im < Zero::zero() { format!("{}{pre}{re}-{pre}{im}i", sign, re=real, im=imag, pre=prefix) } @@ -1314,18 +1302,17 @@ mod test { assert_eq!(format!("{}", a), "1.23456+123.456i"); assert_eq!(format!("{:.2}", a), "1.23+123.46i"); assert_eq!(format!("{:.2e}", a), "1.23e0+1.23e2i"); - assert_eq!(format!("{:+020.2E}", a), "+0001.23E0+001.23E2i"); + assert_eq!(format!("{:+20.2E}", a), " +1.23E0+1.23E2i"); let b = Complex::new(0x80, 0xff); assert_eq!(format!("{:X}", b), "80+FFi"); assert_eq!(format!("{:#x}", b), "0x80+0xffi"); assert_eq!(format!("{:+#b}", b), "+0b10000000+0b11111111i"); assert_eq!(format!("{:+#16o}", b), " +0o200+0o377i"); - assert_eq!(format!("{:+#016x}", b), "+0x00080+0x00ffi"); let c = Complex::new(-10, -10000); assert_eq!(format!("{}", c), "-10-10000i"); - assert_eq!(format!("{:016}", c), "-0000010-010000i"); + assert_eq!(format!("{:16}", c), " -10-10000i"); } #[test]