So, you want to truncate the numbers at the second digit? Beware that rounding might be the better and more accurate solution anyway.

If you want to truncate the numbers, there are a couple of ways - one of them is to multiply the number by 10 elevated to the number of desired decimal places (100 for 2 places), apply "math.floor", and divide the total back by the same number.

However, as internal floating point arithmetic is not base 10, you'd risk getting more decimal places on the division to scale down.

Another way is to create a string with 3 digits after the "." and drop the last one - that'd be rounding proof.

And again, keep in mind that this converts the numbers to strings - what should be done for presentation purposes only. Also, "%" formatting is quite an old way to format parameters in a string. In modern Python, f-strings are the preferred way:

g1 = [f"{number:.03f}"[:-1] for number in g]

Another, more correct way, is, of course, treat numbers as numbers, and not play tricks on adding or removing digits on it. As noted in the comments, the method above would work for numbers like "1.227", that would be kept as "1.22", but not for "2.99999", which would be rounded to "3.000" and then truncated to "3.00". Python has the decimal modules, which allows for arbitrary precision of decimal numbers - which includes less precision, if needed, and control of the way Python does the rounding - including rounding towards zero, instead of the nearest number.

Just set the decimal context to the decimal.ROUND_DOWN strategy, and then convert your numbers using either the round built-in (the exact number of digits is guaranteed, unlike using round with floating point numbers), or just do the rounding as part of the string formatting anyway. You can also convert your floats do Decimals in the same step:

from decimals import Decimal as D, getcontext, ROUND_DOWN

getcontext().rounding = ROUND_DOWN

g1 = [f"{D(number):.02f}" for number in g]

Again - by doing this, you could as well keep your numbers as Decimal objects, and still be able to perform math operations on them:

g2 = [round(D(number, 2)) for number in g]
Answer from jsbueno on Stack Overflow
๐ŸŒ
Quora
quora.com โ€บ How-do-you-truncate-to-2-decimal-places-in-Python
How to truncate to 2 decimal places in Python - Quora
Answer (1 of 2): There are two ways to perform this. Method 1: Using โ€œ%โ€ operator Syntax: float(โ€œ%.2fโ€%number) Explanation: The number 2 in above syntax represents the number of decimal places you want the value to round off too. Method 2: Using round() function Syntax: round(number,2) ...
Top answer
1 of 4
2

So, you want to truncate the numbers at the second digit? Beware that rounding might be the better and more accurate solution anyway.

If you want to truncate the numbers, there are a couple of ways - one of them is to multiply the number by 10 elevated to the number of desired decimal places (100 for 2 places), apply "math.floor", and divide the total back by the same number.

However, as internal floating point arithmetic is not base 10, you'd risk getting more decimal places on the division to scale down.

Another way is to create a string with 3 digits after the "." and drop the last one - that'd be rounding proof.

And again, keep in mind that this converts the numbers to strings - what should be done for presentation purposes only. Also, "%" formatting is quite an old way to format parameters in a string. In modern Python, f-strings are the preferred way:

g1 = [f"{number:.03f}"[:-1] for number in g]

Another, more correct way, is, of course, treat numbers as numbers, and not play tricks on adding or removing digits on it. As noted in the comments, the method above would work for numbers like "1.227", that would be kept as "1.22", but not for "2.99999", which would be rounded to "3.000" and then truncated to "3.00". Python has the decimal modules, which allows for arbitrary precision of decimal numbers - which includes less precision, if needed, and control of the way Python does the rounding - including rounding towards zero, instead of the nearest number.

Just set the decimal context to the decimal.ROUND_DOWN strategy, and then convert your numbers using either the round built-in (the exact number of digits is guaranteed, unlike using round with floating point numbers), or just do the rounding as part of the string formatting anyway. You can also convert your floats do Decimals in the same step:

from decimals import Decimal as D, getcontext, ROUND_DOWN

getcontext().rounding = ROUND_DOWN

g1 = [f"{D(number):.02f}" for number in g]

Again - by doing this, you could as well keep your numbers as Decimal objects, and still be able to perform math operations on them:

g2 = [round(D(number, 2)) for number in g]
2 of 4
1

Here is my solution where we don't even need to convert the number's to string to get the desired output:

def format_till_2_decimal(num):
    return int(num*100)/100.0


g = [-5.427926, -12.222018, 7.214379, -16.771845, -6.1441464, 10.1383295, 14.740516, 5.9209185, -9.740783, -10.098338]

formatted_g = [format_till_2_decimal(num) for num in g]
print(formatted_g)

Hope this solution helps!!

๐ŸŒ
TradingCode
tradingcode.net โ€บ python โ€บ math โ€บ truncate-decimals
Truncate numbers to decimal places in Python โ€ข TradingCode
To use the custom truncate() function we call it with two values: a floating-point value and the number of decimal places to truncate to. For example: ... Truncation is something else than rounding.
๐ŸŒ
datagy
datagy.io โ€บ home โ€บ python posts โ€บ python strings โ€บ python: truncate a float (6 different ways)
Python: Truncate a Float (6 Different Ways) โ€ข datagy
April 14, 2024 - The int() function works differently than the round() and floor() function (which you can learn more about here). The function only removes anything following the decimal, regardless of what follows it.
Find elsewhere
Top answer
1 of 16
164

First, the function, for those who just want some copy-and-paste code:

def truncate(f, n):
    '''Truncates/pads a float f to n decimal places without rounding'''
    s = '{}'.format(f)
    if 'e' in s or 'E' in s:
        return '{0:.{1}f}'.format(f, n)
    i, p, d = s.partition('.')
    return '.'.join([i, (d+'0'*n)[:n]])

This is valid in Python 2.7 and 3.1+. For older versions, it's not possible to get the same "intelligent rounding" effect (at least, not without a lot of complicated code), but rounding to 12 decimal places before truncation will work much of the time:

def truncate(f, n):
    '''Truncates/pads a float f to n decimal places without rounding'''
    s = '%.12f' % f
    i, p, d = s.partition('.')
    return '.'.join([i, (d+'0'*n)[:n]])

Explanation

The core of the underlying method is to convert the value to a string at full precision and then just chop off everything beyond the desired number of characters. The latter step is easy; it can be done either with string manipulation

i, p, d = s.partition('.')
'.'.join([i, (d+'0'*n)[:n]])

or the decimal module

str(Decimal(s).quantize(Decimal((0, (1,), -n)), rounding=ROUND_DOWN))

The first step, converting to a string, is quite difficult because there are some pairs of floating point literals (i.e. what you write in the source code) which both produce the same binary representation and yet should be truncated differently. For example, consider 0.3 and 0.29999999999999998. If you write 0.3 in a Python program, the compiler encodes it using the IEEE floating-point format into the sequence of bits (assuming a 64-bit float)

0011111111010011001100110011001100110011001100110011001100110011

This is the closest value to 0.3 that can accurately be represented as an IEEE float. But if you write 0.29999999999999998 in a Python program, the compiler translates it into exactly the same value. In one case, you meant it to be truncated (to one digit) as 0.3, whereas in the other case you meant it to be truncated as 0.2, but Python can only give one answer. This is a fundamental limitation of Python, or indeed any programming language without lazy evaluation. The truncation function only has access to the binary value stored in the computer's memory, not the string you actually typed into the source code.1

If you decode the sequence of bits back into a decimal number, again using the IEEE 64-bit floating-point format, you get

0.2999999999999999888977697537484345957637...

so a naive implementation would come up with 0.2 even though that's probably not what you want. For more on floating-point representation error, see the Python tutorial.

It's very rare to be working with a floating-point value that is so close to a round number and yet is intentionally not equal to that round number. So when truncating, it probably makes sense to choose the "nicest" decimal representation out of all that could correspond to the value in memory. Python 2.7 and up (but not 3.0) includes a sophisticated algorithm to do just that, which we can access through the default string formatting operation.

'{}'.format(f)

The only caveat is that this acts like a g format specification, in the sense that it uses exponential notation (1.23e+4) if the number is large or small enough. So the method has to catch this case and handle it differently. There are a few cases where using an f format specification instead causes a problem, such as trying to truncate 3e-10 to 28 digits of precision (it produces 0.0000000002999999999999999980), and I'm not yet sure how best to handle those.

If you actually are working with floats that are very close to round numbers but intentionally not equal to them (like 0.29999999999999998 or 99.959999999999994), this will produce some false positives, i.e. it'll round numbers that you didn't want rounded. In that case the solution is to specify a fixed precision.

'{0:.{1}f}'.format(f, sys.float_info.dig + n + 2)

The number of digits of precision to use here doesn't really matter, it only needs to be large enough to ensure that any rounding performed in the string conversion doesn't "bump up" the value to its nice decimal representation. I think sys.float_info.dig + n + 2 may be enough in all cases, but if not that 2 might have to be increased, and it doesn't hurt to do so.

In earlier versions of Python (up to 2.6, or 3.0), the floating point number formatting was a lot more crude, and would regularly produce things like

>>> 1.1
1.1000000000000001

If this is your situation, if you do want to use "nice" decimal representations for truncation, all you can do (as far as I know) is pick some number of digits, less than the full precision representable by a float, and round the number to that many digits before truncating it. A typical choice is 12,

'%.12f' % f

but you can adjust this to suit the numbers you're using.


1Well... I lied. Technically, you can instruct Python to re-parse its own source code and extract the part corresponding to the first argument you pass to the truncation function. If that argument is a floating-point literal, you can just cut it off a certain number of places after the decimal point and return that. However this strategy doesn't work if the argument is a variable, which makes it fairly useless. The following is presented for entertainment value only:

def trunc_introspect(f, n):
    '''Truncates/pads the float f to n decimal places by looking at the caller's source code'''
    current_frame = None
    caller_frame = None
    s = inspect.stack()
    try:
        current_frame = s[0]
        caller_frame = s[1]
        gen = tokenize.tokenize(io.BytesIO(caller_frame[4][caller_frame[5]].encode('utf-8')).readline)
        for token_type, token_string, _, _, _ in gen:
            if token_type == tokenize.NAME and token_string == current_frame[3]:
                next(gen) # left parenthesis
                token_type, token_string, _, _, _ = next(gen) # float literal
                if token_type == tokenize.NUMBER:
                    try:
                        cut_point = token_string.index('.') + n + 1
                    except ValueError: # no decimal in string
                        return token_string + '.' + '0' * n
                    else:
                        if len(token_string) < cut_point:
                            token_string += '0' * (cut_point - len(token_string))
                        return token_string[:cut_point]
                else:
                    raise ValueError('Unable to find floating-point literal (this probably means you called {} with a variable)'.format(current_frame[3]))
                break
    finally:
        del s, current_frame, caller_frame

Generalizing this to handle the case where you pass in a variable seems like a lost cause, since you'd have to trace backwards through the program's execution until you find the floating-point literal which gave the variable its value. If there even is one. Most variables will be initialized from user input or mathematical expressions, in which case the binary representation is all there is.

2 of 16
160
round(1.923328437452, 3)

See Python's documentation on the standard types. You'll need to scroll down a bit to get to the round function. Essentially the second number says how many decimal places to round it to.

๐ŸŒ
PythonHow
pythonhow.com โ€บ how โ€บ limit-floats-to-two-decimal-points
Here is how to limit floats to two decimal points in Python
The format string specifies the desired formatting for the value, and the {:.2f} syntax specifies that the value should be formatted as a float with two decimal points. Both round and format can be used to limit floats to a fixed number of decimal points in Python.
๐ŸŒ
Reddit
reddit.com โ€บ r/learnpython โ€บ how to truncate a float?
r/learnpython on Reddit: How to truncate a float?
July 1, 2022 -

I have a case where I need to truncate a float to the first decimal place. Very important - truncate, not round.

I wrote this function

def trunc(num : float, precision :int = 1):
    return float(str(num)[0:precision+2])

which works most of the time, but if the number is particularly small, str(num) will return the scientific notation. So str(0.000094) returns 9.4e-05 which in turn means that str(0.000094)[0:3] returns 9.4.

For now I can np.trunc(num*10)/10 but I'm wondering if there's a better way.

Top answer
1 of 5
9

You shouldn't use floating point numbers for currency, due to rounding errors like you mentioned.

Your best bet is to use a fixed-precision decimal where you also have full control over how rounding and truncation works. From the docs:

>>> from decimal import *
>>> getcontext()
Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=-999999999, Emax=999999999,
    capitals=1, flags=[], traps=[Overflow, DivisionByZero,
    InvalidOperation])

>>> getcontext().prec = 6
>>> Decimal('3.0')
Decimal('3.0')
>>> Decimal('3.1415926535')
Decimal('3.1415926535')
>>> Decimal('3.1415926535') + Decimal('2.7182818285')
Decimal('5.85987')
>>> getcontext().rounding = ROUND_UP
>>> Decimal('3.1415926535') + Decimal('2.7182818285')
Decimal('5.85988')

You should represent all currency-based values internally as Decimals with a high precision (the standard level of precision should be fine in your case - just leave the prec alone!). If you want to print a nicely formatted dollars and cents value to the user, using the locale module is a straightforward way to do this.

Be careful when printing as you will have to quantize the Decimal down to the correct number of places for display or the rounding will not be based on your Decimal context! You should only perform the quantize step for final display or for a single, final value - all intermediate steps should use high-precision Decimals to make any operations as accurate as possible.

>>> from decimal import *
>>> import locale
>>> locale.setlocale(locale.LC_ALL, '')
'en_AU.UTF-8'
>>> getcontext().rounding = ROUND_DOWN
>>> TWOPLACES = Decimal(10) ** -2
>>> var = Decimal('5.74536541')
Decimal('5.74536541')
>>> var.quantize(TWOPLACES)
Decimal('5.74')
>>> locale.currency(var.quantize(TWOPLACES))
'$5.74'
2 of 5
4

If you're dealing with currency and accuracy matters, don't use float, use decimal.

๐ŸŒ
pythoncodelab
pythoncodelab.com โ€บ home โ€บ how to truncate decimals in python
How to truncate decimals in Python - pythoncodelab
February 8, 2025 - One of the simplest ways to truncate a decimal number in Python is by using the built-in int() function. This function converts a float to an integer by removing the decimal part, effectively truncating the number.
๐ŸŒ
Stack Abuse
stackabuse.com โ€บ bytes โ€บ limiting-float-decimal-points-in-python
Limiting Float Decimal Points in Python
August 31, 2023 - To achieve the truncation, we multiply the float by 100, convert it to an integer to remove the excess decimal points, and then divide it by 100 to get the truncated value. In this Byte, we explored different ways to limit a float's decimal points in Python using the round(), format(), and ...
๐ŸŒ
GeeksforGeeks
geeksforgeeks.org โ€บ python โ€บ how-to-round-floating-value-to-two-decimals-in-python
How to Round Floating Value to Two Decimals in Python - GeeksforGeeks
July 23, 2025 - In this article, we will round off a float value in Python to the nearest two decimal places. Python provides us with multiple approaches to format numbers to 2 decimal places.