Format specifiers for engineers

Python already provides convenient c-like formatting

f"{x:.3f}"
f"{x:.3e}"
f"{x:.3g}"

However, there is no corresponding built-in format for engineering notation, where the exponent is restricted to integer multiples of three.

For example, a possible format specifier could be i:

f"{12345:.4i}" # 12.35e+3
f"{0.12345:.4i}" # 123.5e-3
f"{12.345:.4i}" # 12.35
f"{0.000012345:.4i}" # 12.35e-6

The precision would specify the number of significant digits.

Engineering notation reflects the way engineers commonly handle quantities in the real world. We write 10 km rather than 1e4 m, and 22 pF rather than 2.2e-11 F. Many CAD and engineering tools already use this style of number representation (e.g. my HP desk calculator).

i think, it would be really useful to have engineering notation directly available through Python’s standard format specification mini-language.

The exact format character is of course open for discussion; 4i is only one possible choice.

Would such an extension be considered useful and appropriate for Python’s built-in numeric formatting?

Format specifiers try to follow C standards and while we have some extensions, they are extensions that are usually already widely used elsewhere.

I think this would add a burden on the interpreter’s side that can be solved through a 3rd party library suchas engineering_notation (though it may lack the exact features you are looking for).

Now, if you don’t bother about using Decimal, there is decimal.Decimal.to_eng_string() and decimal.Context.to_eng_string() which already formats in engineering notation.

I believe it’s better we leave it to decimal contexts rather than having a general format specifier (which would leave us with less letters for future standard ones).

1 Like

There have been discussions about adding this before, but of course now I can’t find them. I want to say there was a github issue about it. I realize this isn’t very helpful, but if you want to pursue it, you could try and find that issue first.

To me, this is a ‘locale’ issue, with local language conventions. I imagine that there are multiple sublocales even in engineering. Instead of trying to accommodate an increasing number of these, maybe we should add a generic hook. For f/t strings, add conversion ‘x’, where ‘x’ is defined by sys.xconverter, a function that receives the object being converted and the specifier between ‘:’ and ‘}’. The latter need not be limited to our standard mini-language. It could, for instance, specify a unit, like ‘f’, and the converter could apply unit-specific conversions, like to ‘pf’ and adjust the power.

1 Like

Thanks, that makes sense.

My main motivation was to have engineering notation available as conveniently for ordinary floating-point values as f, e, and g, since this notation is very common in engineering practice and many engineering tools already use it.

I was not aware of Decimal.to_eng_string(). That is useful to know.

For my own use, I will probably stay with a small formatting function for float values rather than converting numerical results to Decimal just for presentation.

There’s humanize.metric() if you don’t mind the dependency.

>>> humanize.metric(22e-12, "F")
'22.0 pF'