Forcing the '+' sign in the exponent part of a scientific notation


#1

I would like to know if it is possible to force the ‘+’ sign to be printed in the exponent part of a float.

Example of working code:

let v = 1.34e+2;
let val_str = format!("{:+e}", val);
assert_eq!("+1.34e2", val_str);

I would like to force the output to be: +1.34e+2 or like in C +1.34e+02.

(This is useful when generating human readable results in a column that may contains negative exponential).

Thanks in advance.


#2

Here’s an example that does it, plus right-aligned 9 chars wide:

for v in &[1.34e+2, -1.34e+2, 1.34e-2, -1.34e-2]  {
    println!("{: >+9e}", v);
}

This produces:

  +1.34e2
  -1.34e2
 +1.34e-2
 -1.34e-2

For full details of rust’s format language see std::fmt syntax.

I can’t see if it is possible to control the format of the e part beyond E or e, i.e., how to set the number of digits after the e or whether you can force the sign to appear (which perhaps isn’t valid anyway).


#3

Thank you for the reply @mark.

The output I would like to obtain is (with or without the padding 0):

+1.34e+02
-1.34e+02
+1.34e-02
-1.34e-02

Although I spent quite a long time reading the doc std::fmt syntax , I have not been able to find information about the exponent of the scientific notation.

(I also miss the equivalent of the C printf %g).


#4

Well…
You could just use the libc::printf function, although I think that that may defeat the purpose.:yum:


#5

I wish I had time to finish this proposal:


#6

Additional thoughts.

There are at least 3 motivations to format a float into a string:

  • having a developper-facing output for debug purposes (Debug trait)
  • having the smallest possible String to be used in an ASCII serialization aimed at being consumed by other softwares (CSV, JSON, …)
  • having a user-facing output, i.e. an ASCII serialization aimed at being visualized (showing, e.g., well-aligned table rows)

In the two first cases, the 1.24e2 output is perfectly valid.
In the last case, the best compromise in order to keep the format syntax complexity low
is probably the C choice, i.e. exponent of width 3 (f32) or 4 (f64) starting with the sign and possibly followed by leading zeros.
The reason simply being that the range of exponent values for a f32 is [-38, +38] and [-308, +308] for a f64.


#7

This assumes that the data will be displayed in columns. I would assert that “d = 2.5e+001 meters, t = 1e-001 seconds” is less easy for human reading than “d = 25 meters, t = 0.1 seconds”. The optimal formatting is far less simple than you are making it out to be.

In many cases the scientific notation is among the worst possible, since the most significant digits are placed at the opposite ends of a possibly very long string. Aligned decimal places can be way more clear, but of course add their own set of limitations.


#8

Printing human readable tabular data is a very common task (at least in my biased experience).

I agree, but this post is focused on the exponent part of the scientific notation (assuming we already made the choice of the scientific notation), which is probably not the best choice in your example.

It depends on the range of possible values of the variable one want to print.
For example, if a scientist is used to a physical quantity possibly ranging (in his field/in the particular context of his code) from 1e-10 to 1e-15, he will probably choose %e instead of %f (neglecting here possible flags, width, precision, … to possibly align, suppress physically insignificant digits, …).

I don’t think it is a problem since we know that human reading is not linear. The eyes will probably jump to the exponent part (it is easier with a well aligned pattern, including signs), before reading the mantissa part.

P.S: I am a big fan of Rust, using it at work