Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"%11f" notation in Python printing too many digits

Tags:

python

string

In Python, I am trying to convert floating point numbers to strings such that the string is exactly 12 characters long: the first character is a space and the remaining characters can be filled with the digits (and decimal point if needs be) of the number to be converted to a string. Also, the numbers need to be expressed in decimal form (no scientific notation). I am working inside a fixed format in a particular file; hence the exact parameters stated above. It can be assumed that all numbers I'm working with are less than 1e12, i.e., that all numbers can be expressed with

I am using

s = " %11f" % number

Most of the floating point numbers convert to a string fitting my formatting parameters just fine; however, some of the larger numbers don't. For example,

print " %11f" % 325918.166005444

gives 325918.166005. This takes up 13 characters, not 11.

Why is my code doing this, and how can I fix this? I'd like to keep as much precision as possible (i.e., simply truncating the fractional portion of the number is not a good enough solution).

If Python version is important, I'm using 2.7.

like image 535
NeutronStar Avatar asked Jun 27 '17 21:06

NeutronStar


2 Answers

You didn't specify a precision, so the default precision for floats, 6, is used. You need both width and precision to get a precise (pun not intended) output.

Also note that:

width is a decimal integer defining the minimum field width. If not specified, then the field width will be determined by the content.

So the precision does more to decide the overall width of the string here.

You could apply new style formatting to gain more control with specifying the width and precision:

>>> num = 325918.166005444
>>> w = 11
>>> " {:{w}.{p}f}".format(num, w=w, p=len(repr(num))-w-1) # subtract 1 for the dot
' 325918.1660'

This, however, assumes that your float is always larger than the width, otherwise, you could first pad the float with trailing zeros after the decimal.

like image 177
Moses Koledoye Avatar answered Oct 13 '22 21:10

Moses Koledoye


Building on Moses Koledoye's answer, here's what I got to work:

num = 325918.166005444
w = 11
p = w-len(str(int(num)))-1
if p <=0: # If it's short enough
   print " %11f" % num
else: # If it's too long
   print " {:{w}.{p}f}".format(num, w=w, p=p)
like image 25
NeutronStar Avatar answered Oct 13 '22 23:10

NeutronStar