# Format specifier for non-scientific notation?

**URL:** <https://internals.rust-lang.org/t/format-specifier-for-non-scientific-notation/16005>\
**Category:** language design\
**Created:** [January 22, 2022, 8:11am UTC](https://internals.rust-lang.org/t/format-specifier-for-non-scientific-notation/16005 "2022-01-22T08:11:21Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![jtempest](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jtempest/32/8977_2.png) [@jtempest](https://internals.rust-lang.org/u/jtempest)\
**Post date:** [January 22, 2022, 8:11am UTC](https://internals.rust-lang.org/t/format-specifier-for-non-scientific-notation/16005/1 "2022-01-22T08:11:21Z")

</div>

In Rust 1.58, the debug output format for float primitives changed. Now, if they are above or below a certain threshold (very small or very large), they are written using scientific notation. Debug output formats are not guaranteed stable, so this is fine in terms of regression and I imagine is going to be helpful for general usage. However, I believe that this has made it impossible to get the old non-scientific output, whilst there are two specifiers ('e' and 'E') that may be provided to print scientific notation directly. Might it be possible to add a specifier to disable this behaviour and just print the digits out?

My personal motivation for asking is that the old behaviour makes it easier to compare and reason about diff values side by side:

```rust
    left: `1.0`,
   right: `1.0000002`,
abs_diff: `0.00000023841858`,

```

Compared with:

```rust
    left: `1.0`,
   right: `1.0000002`,
abs_diff: `2.3841858e-7`,

```

([Print float values in asserts in non-scientific format · Issue #21 · jtempest/float\_eq-rs · GitHub](https://github.com/jtempest/float_eq-rs/issues/21))

---

<div class="post-metadata">

**Author:** ![scottmcm](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/scottmcm/32/2355_2.png) [@scottmcm](https://internals.rust-lang.org/u/scottmcm)\
**Post date:** [January 22, 2022, 9:12am UTC](https://internals.rust-lang.org/t/format-specifier-for-non-scientific-notation/16005/2 "2022-01-22T09:12:29Z")

</div>

> [@jtempest](#):
>
> However, I believe that this has made it impossible to get the old non-scientific output

You might be looking for [https://doc.rust-lang.org/std/fmt/#precision](https://doc.rust-lang.org/std/fmt/#precision)?

---

<div class="post-metadata">

**Author:** ![jtempest](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jtempest/32/8977_2.png) [@jtempest](https://internals.rust-lang.org/u/jtempest)\
**Post date:** [January 22, 2022, 9:21am UTC](https://internals.rust-lang.org/t/format-specifier-for-non-scientific-notation/16005/3 "2022-01-22T09:21:08Z")

</div>

Ah, right, precision nearly covers it but I suppose what I'm looking for is variable precision output without trailing 0s.

---

<div class="post-metadata">

**Author:** ![steffahn](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/steffahn/32/13288_2.png) [@steffahn](https://internals.rust-lang.org/u/steffahn)\
**Post date:** [January 22, 2022, 9:26am UTC](https://internals.rust-lang.org/t/format-specifier-for-non-scientific-notation/16005/4 "2022-01-22T09:26:44Z")

</div>

Debug output doesn't support `e` or `E` specifiers. [`Display` hasn't changed](https://godbolt.org/z/jq97GfPbT) and uses no scientific notation. Hence I don't quite get your point that

> [@jtempest](#):
>
> I believe that this has made it impossible to get the old non-scientific output, whilst there are two specifiers ('e' and 'E') that may be provided to print scientific notation directly

If using `e` or `E` (for using `LowerExp`/`UpperExp`) is an option for your use-case, then removing the `?` (in order to use `Display` instead of `Debug`) will be an option, too. I.e. your `float_eq` crate could just use `Display` implementations, right?

---

<div class="post-metadata">

**Author:** ![jtempest](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jtempest/32/8977_2.png) [@jtempest](https://internals.rust-lang.org/u/jtempest)\
**Post date:** [January 22, 2022, 9:42am UTC](https://internals.rust-lang.org/t/format-specifier-for-non-scientific-notation/16005/5 "2022-01-22T09:42:34Z")

</div>

> [@steffahn](#):
>
> If using `e` or `E` (for using `LowerExp` / `UpperExp` ) is an option for your use-case, then removing the `?` (in order to use `Display` instead of `Debug` ) will be an option, too. I.e. your `float_eq` crate could just use `Display` implementations, right?

Ah, I hadn't actually realised that `LowerExp` / `UpperExp` were distinct from `Debug`, which means that yes, that point doesn't make sense. In terms of library output, it's from `assert!` style macros so I'd want to still use `{:?}` since many, if not most, of the types it supports don't have `Display` implementations. I suppose really my ask is then to have a precision mode that allows for printing digits as required to bring back the possibility of using the old behaviour? Since precision is something that `Debug` does support.

---

<div class="post-metadata">

**Author:** ![steffahn](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/steffahn/32/13288_2.png) [@steffahn](https://internals.rust-lang.org/u/steffahn)\
**Post date:** [January 22, 2022, 9:56am UTC](https://internals.rust-lang.org/t/format-specifier-for-non-scientific-notation/16005/6 "2022-01-22T09:56:23Z")

</div>

I do appreciate the change that something like

```rust
fn main() {
    let x = (f64::MIN_POSITIVE, f64::MAX);
    dbg!(x);
}

```

does now produce legible output. Since `Debug` doesn't currently accept any flags that could specify whether or not scientific notation should be used, I feel like the new behavior now is better than the old, and without extending the set of flags that `Debug` accepts and `Formatter` offers, I don't see how the situation can be improved.

If anything, I feel like the fact that specifying precision still makes it switch back to non-scientific formatting feels slightly inconsistent; maybe there's a different behavior that could make sense? 🤔

In light of the fact that `Debug` _does_ also, somehow, accept and handle ([for built-in integer types, using non-public API](https://doc.rust-lang.org/1.58.1/src/core/fmt/mod.rs.html#1868-1876)) the combination of `x` with `?` does however mean that it's not completely out of the question that `e` could be supported, too, in which case your point about not being able to specify a "never scientific notation" mode would become valid.

---

<div class="post-metadata">

**Author:** ![ExpHP](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/exphp/32/6208_2.png) [@ExpHP](https://internals.rust-lang.org/u/ExpHP)\
**Post date:** [January 25, 2022, 7:50pm UTC](https://internals.rust-lang.org/t/format-specifier-for-non-scientific-notation/16005/7 "2022-01-25T19:50:03Z")

</div>

> [@steffahn](#):
>
> If anything, I feel like the fact that specifying precision still makes it switch back to non-scientific formatting feels slightly inconsistent; maybe there's a different behavior that could make sense? 🤔

As I mentioned [in the PR](https://github.com/rust-lang/rust/pull/86479) that made this change, this decision was motivated by backwards compatibility concerns that existing code which uses a precision may be significantly more likely to be adversely affected by this change than code not using a precision, especially when used on `&[f64]` or similar homogenous containers. But I don't have any actual data on this.

The effect would be even worse if adjusting the precision had an impact on the upper threshold, which is a common property of `%g` in other languages. `100.000` might become `1.00e2`.

On numerous occasions such as this, I have lamented the lack of a `:f`/`Fixed` format in Rust. IMO, the existing behavior ought to be spelled `{:.3f?}` instead of `{:.3?}`...

---

<div class="post-metadata">

**Author:** ![jtempest](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jtempest/32/8977_2.png) [@jtempest](https://internals.rust-lang.org/u/jtempest)\
**Post date:** [January 26, 2022, 12:58am UTC](https://internals.rust-lang.org/t/format-specifier-for-non-scientific-notation/16005/8 "2022-01-26T00:58:13Z")

</div>

Also FWIW I think the change to the default behaviour of `{:?}` was a good one! I just also think that the old behaviour has uses as well if explicitly requested.

---

<div class="post-metadata">

**Author:** ![martin-t](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/martin-t/32/6130_2.png) [@martin-t](https://internals.rust-lang.org/u/martin-t)\
**Post date:** [January 31, 2022, 4:31am UTC](https://internals.rust-lang.org/t/format-specifier-for-non-scientific-notation/16005/9 "2022-01-31T04:31:10Z")

</div>

> [@steffahn](#):
>
> If using `e` or `E` (for using `LowerExp` / `UpperExp` ) is an option for your use-case, then removing the `?` (in order to use `Display` instead of `Debug` ) will be an option, too.

FWIW, `Display` and `Debug` have at least one other difference: `Display` prints `0.0` as "0" but `Debug` prints it as "0.0".

I too would like to be able to disable scientific notation. My usecase it very simple, i want all numbers to have the same xxx.yyy format so they're easy to copy using multiple carets (with ctrl+shift+arrows, i don't want or need the same number of digits on each line). I can't be the only one who wants an easy way to get this consistent format. (I don't think using `Display` and setting precision would work for me because i'd like to avoid trailing zeros.)

---

<div class="post-metadata">

**Author:** ![rkuhn](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/rkuhn/32/6659_2.png) [@rkuhn](https://internals.rust-lang.org/u/rkuhn)\
**Post date:** [January 31, 2022, 6:54am UTC](https://internals.rust-lang.org/t/format-specifier-for-non-scientific-notation/16005/10 "2022-01-31T06:54:50Z")

</div>

In my opinion this issue is caused by a difference of purpose: `Debug` is meant to convey some runtime value to a programmer in text form in a context where the type and value are in question (i.e. during debugging). The purpose is therefore to represent the value without ambiguity while not wasting space.

The purpose of your library is a different one, namely to give visual cues based on the knowledge that you’re dealing with floating-point numbers. The top example nicely shows how the brain can absorb one form much quicker than the other, which involves the study of human perception and psychology.

For this reason I think the `{:?}` format specifier cannot solve both cases at the same time. Instead, its stated purpose in the library documentation is unambiguous textual representation, which is valuable and should be kept. Other number formatting schemes — of which there are many! — can be added via simple functions or wrapper types that implement `Display`, but their usage as well as their API design depend on the context. The standard library should offer simple tools that depend very little on the specific context.

* * *

As a side remark, the aforementioned point about `Display` representation of 0.0 and −0.0 is a quirk that should be fixed in my opinion. But then again I’d want to use actual minus signs for prefix and infix operators (since we also use an actual plus sign for addition), not hyphens.

---

<div class="post-metadata">

**Author:** ![system](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/system/32/14092_2.png) [@system](https://internals.rust-lang.org/u/system)\
**Post date:** [May 1, 2022, 6:55am UTC](https://internals.rust-lang.org/t/format-specifier-for-non-scientific-notation/16005/11 "2022-05-01T06:55:07Z")

</div>

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.
