Python Decimals Format

Python Decimals format

If you have Python 2.6 or newer, use format:

'{0:.3g}'.format(num)

For Python 2.5 or older:

'%.3g'%(num)

Explanation:

{0}tells format to print the first argument -- in this case, num.

Everything after the colon (:) specifies the format_spec.

.3 sets the precision to 3.

g removes insignificant zeros. See
http://en.wikipedia.org/wiki/Printf#fprintf

For example:

tests=[(1.00, '1'),
(1.2, '1.2'),
(1.23, '1.23'),
(1.234, '1.23'),
(1.2345, '1.23')]

for num, answer in tests:
result = '{0:.3g}'.format(num)
if result != answer:
print('Error: {0} --> {1} != {2}'.format(num, result, answer))
exit()
else:
print('{0} --> {1}'.format(num,result))

yields

1.0 --> 1
1.2 --> 1.2
1.23 --> 1.23
1.234 --> 1.23
1.2345 --> 1.23

Using Python 3.6 or newer, you could use f-strings:

In [40]: num = 1.234; f'{num:.3g}'
Out[40]: '1.23'

Fixed digits after decimal with f-strings

Include the type specifier in your format expression:

>>> a = 10.1234
>>> f'{a:.2f}'
'10.12'

How can I format a decimal to always show 2 decimal places?

I suppose you're probably using the Decimal() objects from the decimal module? (If you need exactly two digits of precision beyond the decimal point with arbitrarily large numbers, you definitely should be, and that's what your question's title suggests...)

If so, the Decimal FAQ section of the docs has a question/answer pair which may be useful for you:

Q. In a fixed-point application with two decimal places, some inputs have many places and need to be rounded. Others are not supposed to have excess digits and need to be validated. What methods should be used?

A. The quantize() method rounds to a fixed number of decimal places. If the Inexact trap is set, it is also useful for validation:

>>> TWOPLACES = Decimal(10) ** -2       # same as Decimal('0.01')
>>> # Round to two places
>>> Decimal('3.214').quantize(TWOPLACES)
Decimal('3.21')
>>> # Validate that a number does not exceed two places
>>> Decimal('3.21').quantize(TWOPLACES, context=Context(traps=[Inexact]))
Decimal('3.21')
>>> Decimal('3.214').quantize(TWOPLACES, context=Context(traps=[Inexact]))
Traceback (most recent call last):
...
Inexact: None

The next question reads

Q. Once I have valid two place inputs, how do I maintain that invariant throughout an application?

If you need the answer to that (along with lots of other useful information), see the aforementioned section of the docs. Also, if you keep your Decimals with two digits of precision beyond the decimal point (meaning as much precision as is necessary to keep all digits to the left of the decimal point and two to the right of it and no more...), then converting them to strings with str will work fine:

str(Decimal('10'))
# -> '10'
str(Decimal('10.00'))
# -> '10.00'
str(Decimal('10.000'))
# -> '10.000'

How to display a float with two decimal places?

You could use the string formatting operator for that:

>>> '%.2f' % 1.234
'1.23'
>>> '%.2f' % 5.0
'5.00'

The result of the operator is a string, so you can store it in a variable, print etc.

How to round to 2 decimals with Python?

You can use the round function, which takes as its first argument the number and the second argument is the precision after the decimal point.

In your case, it would be:

answer = str(round(answer, 2))

How to display two decimal points in python, when a number is perfectly divisible?

The division works and returns adequate precision in result.

So your problem is just about visualization or exactly:

  • string-representation of floating-point numbers

Formatting a decimal

You can use string-formatting for that.
For example in Python 3, use f-strings:

twoFractionDigits = f"{result:.2f}"

or print(f"{result:.2f}")

The trick does .2f, a string formatting literal or format specifier that represents a floating-point number (f) with two fractional digits after decimal-point (.2).

See also:

  • Fixed digits after decimal with f-strings
  • How to format a floating number to fixed width in Python

Try on the Python-shell:

Python 3.6.9 (default, Dec  8 2021, 21:08:43) 
[GCC 8.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import math
>>> a=1.175 #value of a after some division
>>> result = math.floor(a*100)/100
>>> result
1.17
>>> print(result)
1.17
>>> a=25/5 #Now a is perfectly divisible
>>> result = math.floor(a*100)/100
>>> result
5.0
>>> print(result)
5.0
>>> print(f"{result:.2f}")
5.00

Formatting a decimal as percentage

Similar you can represent the ratio as percentage:
print(f"{result:.2f} %")

prints:

5.00 %

A formatting shortcut for percentage can be:
print(f"{25/100:.2%}")
Which converts the result of 25/100 == 0.25 to:

25.00%

Note: The formatting-literal .2% automatically converts from ratio to percentage with 2 digits after the decimal-point and adds the percent-symbol.

Formatting a decimal with specific scale (rounded or truncated ?)

Now the part without rounding-off, just truncation.
As example we can use the repeating decimal, e.g. 1/6 which needs to be either rounded or truncated (cut-off) after a fixed number of fractional digits - the scale (in contrast to precision).

>>> print(f"{1/6:.2}")
0.17
>>> print(f"{1/6:.2%}")
16.67%

Note how the formatted string is not truncated (to 0.16) but rounded (to 0.17). Here the scale was specified inside formatting-literal as 2 (after the dot).

See also:

  • Truncate to three decimals in Python
  • How do I interpret precision and scale of a number in a database?
  • What is the difference between precision and scale?

Formatting many decimals in fixed width (leading spaces)

Another example is to print multiple decimals, like in a column as right-aligned, so you can easily compare them.

Then use string-formatting literal 6.2f to add leading spaces (here a fixed-width of 6):

>>> print(f"{result:6.2f}")
5.00
>>> print(f"{100/25*100:6.2f}")
400.00
>>> print(f"{25/100*100:6.2f}")
25.00

See also

All the formatting-literals demonstrated here can also be applied using

  • old-style %-formatting (also known as "Modulo string formatting") which was inherited from printf method of C language. Benefit: This way is also compatible with Python before 3.6).
  • new-style .format method on strings (introduced with Python 3)

See theherk's answer which demonstrates those alternatives.

Learn more about string-formatting in Python:

  • Real Python: Python 3's f-Strings: An Improved String Formatting Syntax (Guide)
  • Real Python: Python String Formatting Best Practices

Getting only 1 decimal place

Are you trying to represent it with only one digit:

print("{:.1f}".format(number)) # Python3
print "%.1f" % number # Python2

or actually round off the other decimal places?

round(number,1)

or even round strictly down?

math.floor(number*10)/10

Python formatting leading zeros and optional decimals

Since you don't want a decimal point for special cases, there is no formatting rule.

Workaround:

"{:04.1f}".format(number).replace(".0", "")


Related Topics



Leave a reply



Submit