-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
extend fmt! to add %g analogous to printf '%g' #844
Comments
Any thoughts on possible syntaxes/implementations of this? |
From http://www.cplusplus.com/reference/cstdio/printf/
|
+1 to this. Actually, if it weren't for backwards compatibility, I'd even like this behaviour to become the default. There's plenty of prior art of using this so-called "engineering notation" in scientific calculators, and here's the likely reason: very large and very small numbers, which are quite common in scientific computing, don't mix well with raw decimal formatting at all. And conversely, there is no need to get scientific notation involved for numbers close to 1, where decimal notation is more easily readable. In this sense, the engineering notation is the most sensible default for printing floats of unknown value, because it is the notation which is most likely to feel right for any number. |
Here is a basic implementation based on the existing formatters, which I wrote for a project that needed it more than usual. It differs a bit from printf's %g in that it does not allow itself to add extra zeroes on the back of a large number (as that could give the illusion of more significant digits than were intended). /// Write a floating-point number using "engineering" notation
///
/// Analogous to the %g format of the C printf function, this method switches
/// between naive and scientific notation for floating-point numbers when the
/// number being printed becomes so small that printing leading zeroes could end
/// up larger than the scientific notation, or so large that we would be forced
/// to print more significant digits than requested.
///
pub fn write_engineering(writer: &mut impl Write, x: Real, sig_digits: usize) {
let mut precision = sig_digits - 1;
let log_x = x.abs().log10();
if (log_x >= -3. && log_x <= (sig_digits as Real)) || x == 0. {
// Print using naive notation
if x != 0. {
// Since Rust's precision controls number of digits after the
// decimal point, we must adjust it depending on magnitude in order
// to operate at a constant number of significant digits.
precision = (precision as isize - log_x.trunc() as isize) as usize;
// Numbers smaller than 1 must get one extra digit since the leading
// zero does not count as a significant digit.
if log_x < 0. { precision += 1 }
}
write!(writer, "{:.1$}", x, precision);
} else {
// Print using scientific notation
write!(writer, "{:.1$e}", x, precision);
}
} What upstream integration would bring with respect to this approximation is much greater ease of use (as there is no need to break out of the format string workflow) and access to the other format!() controls: padding, alignment... |
If there is anything I can do to help you get rid of this little papercut, feel free to ask 😉 |
I have implemented something a bit more subtle (and also less efficient) at: /~https://github.com/droundy/sad-monte-carlo/blob/master/src/prettyfloat.rs I format both ways, and then pick whichever is shorter, which I consider a very nice heuristic. |
I would need this right now, for a project that needs to mimic C's |
FWIW I have published https://crates.io/crates/gpoint which is a wrapper around |
Issue by erickt
Thursday Oct 18, 2012 at 23:02 GMT
For earlier discussion, see rust-lang/rust#3810
This issue was labelled with: A-libs, I-enhancement in the Rust repository
It's sometimes nice not to include trailing zeroes when printing floats. It'd be nice if we copied printf's %g to handle this.
The text was updated successfully, but these errors were encountered: