2

I'm using the general formatting option to print floats as strings, but i find the behaviour somewhat unusual. For example, when specifying a precision (number of digits following the decimal point): For float format:

In [1]: '%f' % 123.456
Out[1]: '123.456000'

In [2]: '%.1f' % 123.456
Out[2]: '123.5'

works just as expected. Now, compare this to:

In [3]: '%g' % 123.456
Out[3]: '123.456'

In [4]: '%.1g' % 123.456
Out[4]: '1e+02'

Or even worse:

In [6]: '%5g' % 123.456
Out[6]: '123.456'

In [7]: '%.5g' % 123.456
Out[7]: '123.46'

It seems to be taking the "precision" value to mean "width". Is this a bug, or is it expected behaviour?

Ps. What I want is to print floating point numbers (up to a given precision) with the minimum needed characters. For example: 0.301238 with precision 1 prints as 0.3; 100.0003 with precision 1 prints as 100;

codeMonkey
  • 562
  • 8
  • 19
  • As a note, it's [generally recommended](https://docs.python.org/3.4/library/stdtypes.html#printf-style-string-formatting) to use the more powerful and easier to read [`format()`](https://docs.python.org/3.4/library/functions.html#format) method over `%` formatting in Python. – Gareth Latty Nov 22 '14 at 11:51
  • Roger that, just used the % formatting for readability in the example. Using `format()` gives you the same behaviour. – codeMonkey Nov 22 '14 at 11:58

1 Answers1

1

The formatting spec states:

The precision is a decimal number indicating how many digits should be displayed after the decimal point for a floating point value formatted with 'f' and 'F', or before and after the decimal point for a floating point value formatted with 'g' or 'G'. For non-number types the field indicates the maximum field size - in other words, how many characters will be used from the field content. The precision is not allowed for integer values.

(Emphasis added)

This is the expected behaviour.

I don't believe there is a way to get one significant digit (what you appear to want) using only string formatting. Manually manipulating the number would be required.

>>> from math import log10, floor
>>> def round_to_1(x):
...    return round(x, -int(floor(log10(x))))
...
>>> "{:g}".format(round_to_1(0.301238))
0.3
>>> "{:g}".format(round_to_1(100.0003))
100
Community
  • 1
  • 1
Gareth Latty
  • 86,389
  • 17
  • 178
  • 183
  • Great! Thanks for this solution! You can add arbitrary precision by using `lambda n,p :'{:g}'.format(round(n, p))` – codeMonkey Nov 22 '14 at 12:21