Python floating point format

Nicely representing a floating-point number in python [duplicate]

Is there a better way to do this? Why doesn’t Python have a built-in function for this?

I did miss the asterisk formatting option, however using ‘g’ returns exponents and using ‘f’ is far from perfect: «%.*f» % (0, 34500000000000000000000) returns ‘34499999999999999000000’

You don’t say if this is what you’re doing, but if you’re using floating-point math to do calculations related to money, it is a terrible, terrible idea. Either use the decimal module or store the quantity as an integer cents (or the local currency equivalent). Decimal is really your best bet.

4 Answers 4

It appears there is no built-in string formatting trick which allows you to (1) print floats whose first significant digit appears after the 15th decimal place and (2) not in scientific notation. So that leaves manual string manipulation.

Below I use the decimal module to extract the decimal digits from the float. The float_to_decimal function is used to convert the float to a Decimal object. The obvious way decimal.Decimal(str(f)) is wrong because str(f) can lose significant digits.

float_to_decimal was lifted from the decimal module’s documentation.

Once the decimal digits are obtained as a tuple of ints, the code below does the obvious thing: chop off the desired number of sigificant digits, round up if necessary, join the digits together into a string, tack on a sign, place a decimal point and zeros to the left or right as appropriate.

At the bottom you’ll find a few cases I used to test the f function.

import decimal def float_to_decimal(f): # http://docs.python.org/library/decimal.html#decimal-faq "Convert a floating point number to a Decimal with no loss of information" n, d = f.as_integer_ratio() numerator, denominator = decimal.Decimal(n), decimal.Decimal(d) ctx = decimal.Context(prec=60) result = ctx.divide(numerator, denominator) while ctx.flags[decimal.Inexact]: ctx.flags[decimal.Inexact] = False ctx.prec *= 2 result = ctx.divide(numerator, denominator) return result def f(number, sigfig): # http://stackoverflow.com/questions/2663612/nicely-representing-a-floating-point-number-in-python/2663623#2663623 assert(sigfig>0) try: d=decimal.Decimal(number) except TypeError: d=float_to_decimal(float(number)) sign,digits,exponent=d.as_tuple() if len(digits) < sigfig: digits = list(digits) digits.extend([0] * (sigfig - len(digits))) shift=d.adjusted() result=int(''.join(map(str,digits[:sigfig]))) # Round the result if len(digits)>sigfig and digits[sigfig]>=5: result+=1 result=list(str(result)) # Rounding can change the length of result # If so, adjust shift shift+=len(result)-sigfig # reset len of result to sigfig result=result[:sigfig] if shift >= sigfig-1: # Tack more zeros on the end result+=['0']*(shift-sigfig+1) elif 0 

Источник

How to format a floating number to fixed width in Python

The format specifier inside the curly braces follows the Python format string syntax. Specifically, in this case, it consists of the following parts:

  • The empty string before the colon means "take the next provided argument to format() " – in this case the x as the only argument.
  • The 10.4f part after the colon is the format specification.
  • The f denotes fixed-point notation.
  • The 10 is the total width of the field being printed, lefted-padded by spaces.
  • The 4 is the number of digits after the decimal point.

So I understand that the 4f represents limiting the decimals to 4 (with trailing zeros), but what does the 10 mean? Does that mean this formatting won't work with integers greater than 9999999999 (ten 9's)? Just curious.

@hobbes3: 10 is the minimum field width, i.e. the minimum length of the printed string. Numbers are by default right-aligned and padded with spaces -- see the documentation for more details.

It has been a few years since this was answered, but as of Python 3.6 (PEP498) you could use the new f-strings :

numbers = [23.23, 0.123334987, 1, 4.223, 9887.2] for number in numbers: print(f'') 
 23.2300 0.1233 1.0000 4.2230 9887.2000 

Note that the width also includes dot character. So if you specify 9 to be width, 1 will be used for printing the dot, the other 8 will be for printing digits and spaces.

In python3 the following works:

>>> v=10.4 >>> print('% 6.2f' % v) 10.40 >>> print('% 12.1f' % v) 10.4 >>> print('%012.1f' % v) 0000000010.4 

This has changed in the last 4 years, now % formatting is the oldest method of formatting. For several reasons using str.format or f-strings is preferred over % . Previously when it was only str.format , people had some reasons but f-strings fixed that hole. format mini-language docs, str.format examples from docs and f-string literals examples in docs

You can also left pad with zeros. For example if you want number to have 9 characters length, left padded with zeros use:

Thus, if number = 4.656 , the output is: 00004.656

For your example the output will look like this:

numbers = [23.2300, 0.1233, 1.0000, 4.2230, 9887.2000] for x in numbers: print(''.format(x)) 
00023.2300 00000.1233 00001.0000 00004.2230 09887.2000 

One example where this may be useful is when you want to properly list filenames in alphabetical order. I noticed in some linux systems, the number is: 1,10,11. 2,20,21.

Thus if you want to enforce the necessary numeric order in filenames, you need to left pad with the appropriate number of zeros.

Источник

Читайте также:  Comment in html template
Оцените статью