153

I want to take a floating-point number and round it down to the nearest integer. However, if it's not a whole, I always want to round down the variable, regardless of how close it is to the next integer up. Is there a way to do this?

mkrieger1
  • 19,194
  • 5
  • 54
  • 65
Anthony Perez
  • 1,583
  • 2
  • 9
  • 5

12 Answers12

213
int(x)

Conversion to integer will truncate (towards 0.0), like math.trunc.
For non-negative numbers, this is downward.

If your number can be negative, this will round the magnitude downward, unlike math.floor which rounds towards -Infinity, making a lower value. (Less positive or more negative).

Python integers are arbitrary precision, so even very large floats can be represented as integers. (Unlike in other languages where this idiom could fail for floats larger than the largest value for an integer type.)

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Ghostwriter
  • 2,461
  • 2
  • 16
  • 18
  • 10
    int(0.6) = 0 rather than 1 – Helin Wang Nov 08 '13 at 00:05
  • 54
    @HelinWang That's exactly what OP asked for. – Petr Peller Nov 18 '13 at 09:57
  • 6
    This seems like the most Pythonic approach. – Gyan Veda Jun 16 '14 at 19:40
  • 31
    This works well for positive numbers, but negative numbers will be rounded up: `int(-23.3) == 23` – Alex Riley Nov 08 '14 at 19:36
  • 3
    and does not work for number beyond the integer range such as 600851475143, it will basically flag a memory error. – Ibukun Muyide Jan 20 '16 at 15:26
  • 1
    @MuyideIbukun python? beyond the integer range? – Antony Hatchkins Jan 31 '18 at 05:09
  • @MuyideIbukun `int(-1E99)` gives (at my side) `-999999999999999967336168804116691273849533185806555472917961779471295845921727862608739868455469056L` which looks pretty ok to me. – Tino Jun 03 '18 at 08:26
  • 1
    @AlexRiley While you are mathematically correct, usually the "nearest lower integer" a human wants is towards 0 and not towards -inf. If your account balance is -23.3M$ you will rather think of having -23M than having -24M, right? Same is true if you have -23.9M; You will still pretend it's only -23M as long as you can ;) – Tino Jun 03 '18 at 08:43
  • @Tino But if you had $23.1M, you would definitely want to round it up to $24; so I don't think your example applies here:) – HosseyNJF Aug 25 '19 at 13:16
  • 3
    I like this solution much less than `math.floor`: one should know how `int` function works to see rounding down happens. The solution also relies on a detail of implementation of `int` function (even though it's unlikely to change). `math.floor` on the other hand is explicit: just looking at it is enough to be sure rounding down will happen. – Mikhail Gerasimov Jan 11 '20 at 18:01
  • 1
    As Mikhail said in accordance with Python Zen: Explicit is better than implicit. That's it about using int for rounding values. – AlGiorgio Jan 29 '20 at 11:31
  • 2
    @MikhailGerasimov: This isn't even the same as `math.floor`. Conversion to integer is done with truncation toward 0, like in C. I edited the answer to make it clear to future readers exactly what this does (and introduce readers to the concepts of rounding directions, since if they knew about floor vs. trunc they'd probably not have had to google this.) This involved rewriting the entire text outside the code, so Ghostwriter you might want to rephrase some of it if you think different wording would help future readers the most. – Peter Cordes Mar 07 '23 at 01:51
  • int(0.9999999999999999) >>> 0; however, int(0.99999999999999999) >>> 1. Surely this is an issue given the OP question. – agftrading Jun 26 '23 at 20:06
85

One of these should work:

import math
math.trunc(1.5)
> 1
math.trunc(-1.5)
> -1
math.floor(1.5)
> 1
math.floor(-1.5)
> -2
U2EF1
  • 12,907
  • 3
  • 35
  • 37
  • 15
    The output from `math.trunc` is an integer, while the output of `math.floor` is a float. – evedovelli Nov 29 '13 at 15:33
  • 8
    @evedovelli: Not really anymore. `type(math.floor(1.51)) -> int` and `type(math.trunc(1.51)) -> int` as of `python 3.6.0` – SKPS May 03 '17 at 10:23
  • 5
    These options are more explicit than "int(x)" and hence are more Pythonic. – Tristan Jan 07 '19 at 16:53
54
x//1

The // operator returns the floor of the division. Since dividing by 1 doesn't change your number, this is equivalent to floor but no import is needed. Notes:

  1. This returns a float
  2. This rounds towards -∞
wjandrea
  • 28,235
  • 9
  • 60
  • 81
Huy D
  • 554
  • 4
  • 7
  • Nice addition. `int(-1.1) == -1` while `-1.1//1 == -2.0` however `decimal.Decimal('-1.1')//1 == decimal.Decimal('-1')` (as documented, claim 2 isn't true for `decimal`), so relying on how `//` behaves is not fully stable, even today. – Tino Jun 03 '18 at 08:22
35

To get floating point result simply use:

round(x-0.5)

It works for negative numbers as well.

DmitryG
  • 359
  • 3
  • 2
31

I think you need a floor function :

math.floor(x)

voidMainReturn
  • 3,339
  • 6
  • 38
  • 66
9

a lot of people say to use int(x), and this works ok for most cases, but there is a little problem. If OP's result is:

x = 1.9999999999999999

it will round to

x = 2

after the 16th 9 it will round. This is not a big deal if you are sure you will never come across such thing. But it's something to keep in mind.

wjandrea
  • 28,235
  • 9
  • 60
  • 81
lokilindo
  • 682
  • 5
  • 17
  • 21
    That is because `1.9999999999999999` is actually equal to `2.0` in the internal float64 representation. I. e. it's already rounded as soon as it is parsed into a float, as a 64 bit float cannot represent that many significant digits. You can verify that with evaluating `1.9999999999999999 == 2.0`. And if you suspect that the equals operation does some rounding on floats, you can compare the binary representation with `struct.pack("d", 1.9999999999999999) == struct.pack("d", 2.0)`, which is also equal. – blubberdiblub Sep 06 '15 at 03:26
  • 4
    And if that's exactly your point, then I don't see what's wrong with `int()`. The value is already 2.0 and it will convert it happily into 2. – blubberdiblub Sep 06 '15 at 03:33
  • 1
    If OP's (or whomever reads this in the future) intention is to use the nearest integer ( and not the round-up value) for whatever reason, then it would be something to keep in mind. – lokilindo Aug 13 '16 at 03:45
  • 4
    @lokilindo But this has nothing to do with `int()`, it solely has to do with an **improper use of `float`**, as `1.9999999999999999` is rounded up to `2.0` **at compile time** (while `int()` is called on execution time). If you use the right data type for the variable, everything works as expected: `int(decimal.Decimal('1.9999999999999999999999999999999999999999999999999999999'))` gives `1` – Tino Jun 03 '18 at 08:04
6

If you don't want to import math, you could use:

int(round(x))

Here's a piece of documentation:

>>> help(round)
Help on built-in function round in module __builtin__:

round(...)
    round(number[, ndigits]) -> floating point number

    Round a number to a given precision in decimal digits (default 0 digits).
    This always returns a floating point number.  Precision may be negative.
d33tah
  • 10,999
  • 13
  • 68
  • 158
Tyler
  • 105
  • 1
  • 1
  • Thanks for your answer. Next time you'll get a better reception if you write proper code (close parenthesis), and give some documentation. – Geoff May 29 '14 at 22:20
  • 2
    `round` was already discussed and rejected as an answer when this question was asked a year ago. OP wants `math.floor`. – Adam Smith May 29 '14 at 22:25
3

If you working with numpy, you can use the following solution which also works with negative numbers (it's also working on arrays)

import numpy as np
def round_down(num):
    if num < 0:
        return -np.ceil(abs(num))
    else:
        return np.int32(num)
round_down = np.vectorize(round_down)

round_down([-1.1, -1.5, -1.6, 0, 1.1, 1.5, 1.6])
> array([-2., -2., -2.,  0.,  1.,  1.,  1.])

I think it will also work if you just use the math module instead of numpy module.

Mr Poin
  • 61
  • 4
3

Just make round(x-0.5) this will always return the next rounded down Integer value of your Float. You can also easily round up by do round(x+0.5)

Dominic Nagel
  • 105
  • 2
  • 3
1

Don't know if you solved this, but I just stumble upon this question. If you want to get rid of decimal points, you could use int(x) and it will eliminate all decimal digits. Theres no need to use round(x).

Gaahbon
  • 191
  • 2
-2

It may be very simple, but couldn't you just round it up then minus 1? For example:

number=1.5
round(number)-1
> 1
-6

I used this code where you subtract 0.5 from the number and when you round it, it is the original number rounded down.

round(a-0.5)

  • 2
    What's the difference from [this existed answer](https://stackoverflow.com/a/29651462/5376789)? – xskxzr Oct 25 '18 at 04:11