How can I format printing the scientific number in this way?

I can print:

f32  : [  -3.4028e38,    3.4028e38]
f64  : [ -1.7977e308,   1.7977e308]

with this code:

    println!("f32  : [{:12.4e}, {:12.4e}]", f32::MIN, f32::MAX);
    println!("f64  : [{:12.4e}, {:12.4e}]", f64::MIN, f64::MAX);

but, what I want is this:

f32  : [ -3.4028e 38,   3.4028e 38]
f64  : [ -1.7977e308,   1.7977e308]

Is there any syntax can do that? Or is it even possible?
I tried:

    println!("f32  : [{:12.4e3}, {:12.4e3}]", f32::MIN, f32::MAX);
    println!("f64  : [{:12.4e3}, {:12.4e3}]", f64::MIN, f64::MAX);

It didn't compile!

I believe this is not supported by the format! macro (therefore no supported by println!), a workaround of this is to format as a String and then find the position of the e character, then insert spaces as you want

I've quickly whipped up a wrapper type that provides this feature via an additional exp_width field: Playground.

#[derive(Clone, Copy, Debug)]
struct PadExp<T> {
    num: T,
    exp_width: usize,

impl<T: LowerExp> LowerExp for PadExp<T> {
    fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
        let s = format!("{0:1$.2$e}", self.num, formatter.width().unwrap_or(0), formatter.precision().unwrap_or(0));
        let [head, tail]: [&str; 2] = s.split('e').collect::<Vec<_>>().try_into().unwrap();
        write!(formatter, "{0}e{1:>2$}", head, tail, self.exp_width)

Thanks, I guess I need finish my syntax study before revisiting your code. But I believe it works. :grinning:

Well, it's a quick example, so it doesn't properly handle e.g. the lack of precision/width (note the .unwrap_or(0)s in the code). So ideally, you'd review and improve/extend this so that it handles edge/corner cases correctly as well.

1 Like

Thanks, I'll try it later.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.