Search code examples
pythonstringstring-formatting

String formatting {:d} vs %d on floating point number


I realise that this question could be construed as similar to others, so before I start, here is a list of some possible "duplicates" before everyone starts pointing them out. None of these seem to really answer my question properly.

My question specifically pertains to the use of the string.format() method for displaying integer numbers.

Running the following code using % string formatting in the interpreter running python 2.7

    >>> print "%d" %(1.2345)  
    1

Whereas using the string.format() method results in the following

    >>> print "{:d}".format(1.2345)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    ValueError: Unknown format code 'd' for object type 'float'

I was expecting the same behavior in both; for the interpreter to actually convert my floating point number to an integer prior to displaying. I realise that I could just use the int function to convert the floating point number to integer format, but I was looking for the same functionality you get with the %d formatting method. Is there any string.format() method that would do this for me?


Solution

  • The two implementations are quite separate, and some warts in the % implementation were ironed out. Using %d for floats may mask problems in your code, where you thought you had integers but got floating point values instead. Imagine a value of 1.999999 and only seeing 1 instead of 2 as %d truncates the value.

    As such, the float.__format__() hook method called by str.format() to do the actual conversion work does not support the d format and throws an exception instead.

    You can use the {:.0f} format to explicitly display (rounded) floating point values with no decimal numbers:

    >>> '{:.0f}'.format(1.234)
    '1'
    >>> '{:.0f}'.format(1.534)
    '2'
    

    or use int() before formatting to explicitly truncate your floating point number.

    As a side note, if all you are doing is formatting a number as a string (and not interpolating into a larger string), use the format() function:

    >>> format(1.234, '.0f')
    '1'
    

    This communicates your intent better and is a little faster to boot.