How can I force division to be floating point? Division keeps rounding down to 0?
Asked Answered
T

11

788

I have two integer values a and b, but I need their ratio in floating point. I know that a < b and I want to calculate a / b, so if I use integer division I'll always get 0 with a remainder of a.

How can I force c to be a floating point number in Python 2 in the following?

c = a / b

In 3.x, the behaviour is reversed; see Why does integer division yield a float instead of another integer? for the opposite, 3.x-specific problem.

Throughway answered 12/8, 2009 at 18:25 Comment(1)
That's standard for a typed language: If you divide two integers, the result is an integer, too; mostly to avoid complications for expressions like a = a / 3: If a / 3 were a float type, you couldn't assign it to the original integer type. Most type languages also do "type promotion": If one is float, a float operator is used, and to be able to use it, the other will be promoted (i.e.: converted) to a float. This may seem handy, but in object-oriented programming this can become quite messy if you define your own numeric types. Also this can have an unintended performance impact.Macadamia
I
853

In Python 2, division of two ints produces an int. In Python 3, it produces a float. We can get the new behaviour by importing from __future__.

>>> from __future__ import division
>>> a = 4
>>> b = 6
>>> c = a / b
>>> c
0.66666666666666663
Informed answered 12/8, 2009 at 18:28 Comment(7)
If you go this route and still need some integer division, you can do it like a // bAbomination
Note that in Python 3, this is the default behavior.Imbecilic
It's also the default behavior in the Idle (ipython) shell, but not the ipython script interpreter, which can really cause headaches when debugging scripts run by the default system python interpreter.Gaspar
This doesn't change the behavior of operator.div, though. To do that, use operator.truediv().Whitman
Note that from __future__ import division must be at the very beginning of the fileMidwifery
Thanks for this answer! Was driving me crazy. Why on earth did they choose to do that in Python 2? I've never seen that before.Katusha
@Katusha Python 2 followed a common convention from other languages, particularly C - int divided by int produced int result. In Python 3 they realized that was non-intuitive and changed it.Padova
A
754

You can cast to float by doing c = a / float(b). If the numerator or denominator is a float, then the result will be also.


A caveat: as commenters have pointed out, this won't work if b might be something other than an integer or floating-point number (or a string representing one). If you might be dealing with other types (such as complex numbers) you'll need to either check for those or use a different method.

Abomination answered 12/8, 2009 at 18:28 Comment(4)
I would cast both operands to a float just to make it clearer. Casting just the one that happens to trigger a special code path will be confusing to many people reading the code. You also get stuck in situations that Acute was in.Epiclesis
this is not the better answer than using __future__. b might lose information when cast as float! The correct workaround is to multiply other multiplicand by 1.0.Unspent
@AnttiHaapala is there a specific case where casting to float doesn't work but __future__ does? I'd expect future division to use this same method as its implementation strategy. And how is multiplying by 1.0 different than casting to float?Padova
It will fail for example if the casted argument is something else than a float or int already. The correct approach is discussed in detail in PEP 238.Unspent
B
212

How can I force division to be floating point in Python?

I have two integer values a and b, but I need their ratio in floating point. I know that a < b and I want to calculate a/b, so if I use integer division I'll always get 0 with a remainder of a.

How can I force c to be a floating point number in Python in the following?

c = a / b

What is really being asked here is:

"How do I force true division such that a / b will return a fraction?"

Upgrade to Python 3

In Python 3, to get true division, you simply do a / b.

>>> 1/2
0.5

Floor division, the classic division behavior for integers, is now a // b:

>>> 1//2
0
>>> 1//2.0
0.0

However, you may be stuck using Python 2, or you may be writing code that must work in both 2 and 3.

If Using Python 2

In Python 2, it's not so simple. Some ways of dealing with classic Python 2 division are better and more robust than others.

Recommendation for Python 2

You can get Python 3 division behavior in any given module with the following import at the top:

from __future__ import division

which then applies Python 3 style division to the entire module. It also works in a python shell at any given point. In Python 2:

>>> from __future__ import division
>>> 1/2
0.5
>>> 1//2
0
>>> 1//2.0
0.0

This is really the best solution as it ensures the code in your module is more forward compatible with Python 3.

Other Options for Python 2

If you don't want to apply this to the entire module, you're limited to a few workarounds. The most popular is to coerce one of the operands to a float. One robust solution is a / (b * 1.0). In a fresh Python shell:

>>> 1/(2 * 1.0)
0.5

Also robust is truediv from the operator module operator.truediv(a, b), but this is likely slower because it's a function call:

>>> from operator import truediv
>>> truediv(1, 2)
0.5

Not Recommended for Python 2

Commonly seen is a / float(b). This will raise a TypeError if b is a complex number. Since division with complex numbers is defined, it makes sense to me to not have division fail when passed a complex number for the divisor.

>>> 1 / float(2)
0.5
>>> 1 / float(2j)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can't convert complex to float

It doesn't make much sense to me to purposefully make your code more brittle.

You can also run Python with the -Qnew flag, but this has the downside of executing all modules with the new Python 3 behavior, and some of your modules may expect classic division, so I don't recommend this except for testing. But to demonstrate:

$ python -Qnew -c 'print 1/2'
0.5
$ python -Qnew -c 'print 1/2j'
-0.5j
Bename answered 18/9, 2015 at 17:29 Comment(2)
"1 // 2 = 0", "1 // 2.0 = 0.0" -- interesting little gotcha, even if it's an integer division, if any of the operands is float then the result is a whole number but also float. I was using an integer division to calculate a list index and getting an error because of that.Jubilant
I prefer a / (b + 0.0) just because addition is usually faster than multiplication, even if the difference is negligible.Padova
D
138
c = a / (b * 1.0)
Dyscrasia answered 12/8, 2009 at 18:26 Comment(0)
G
67

In Python 3.x, the single slash (/) always means true (non-truncating) division. (The // operator is used for truncating division.) In Python 2.x (2.2 and above), you can get this same behavior by putting a

from __future__ import division

at the top of your module.

Grecize answered 12/8, 2009 at 18:30 Comment(0)
B
32

Just making any of the parameters for division in floating-point format also produces the output in floating-point.

Example:

>>> 4.0/3
1.3333333333333333

or,

>>> 4 / 3.0
1.3333333333333333

or,

>>> 4 / float(3)
1.3333333333333333

or,

>>> float(4) / 3
1.3333333333333333
Butterfingers answered 24/9, 2010 at 6:22 Comment(4)
But you might later be tempted to do 1.0 + 1/3 or float(c) + a/b or float(a/b) and you'll be disappointed with the answer. Better to use python 3+ or import the __future__.division module, (see accepted answer), to always get the answer you expect. The existing division rules create insidious, hard-to-trace math error.Gaspar
@JoeCondron Did you try python -c 'a=10; b=3.0; print a/b'?Butterfingers
I didn't have to because it obviously works in this scenario. However, what if a and 'b', e.g., are the outputs of an integer-value function? E.g., a = len(list1), b = len(list2).Scarberry
@JoeCondron: good point. I just updated the answer to include float(..). I think multiplying by 1.0, as @Dyscrasia suggested below, could also be useful.Butterfingers
C
22

Add a dot (.) to indicate floating point numbers

>>> 4/3.
1.3333333333333333
Counterproposal answered 22/11, 2014 at 14:39 Comment(2)
How are you going to apply this approach if the numerator and denominator are both variables?Campaign
I assume you refer to the first example, if that is so , i would just use float() on one of the variables.Counterproposal
H
14

This will also work

>>> u=1./5
>>> print u
0.2
Headwater answered 24/12, 2013 at 19:58 Comment(4)
And how are you going to apply this approach if the numerator and denominator are both variables?Campaign
Because it doesn't work when variables are used for abstraction. Almost no meaningful code has values hardcoded like that.Protractile
This has little votes because this answer doesn't answer the question, and isn't a general answer at all. In an answer it's also important first to show why this works. It's very simple: if the numerator or denominator is a float, the result will be a float. Usually you don't use python as a plaintext calculator, so you want an answer for variables a and b.Wellhead
For the longest time, I actually thought ./ was a valid operator in python that allows you to do floating point division. This is why it is good to use white space judiciously, in any programming languageBignonia
A
7

If you want to use "true" (floating point) division by default, there is a command line flag:

python -Q new foo.py

There are some drawbacks (from the PEP):

It has been argued that a command line option to change the default is evil. It can certainly be dangerous in the wrong hands: for example, it would be impossible to combine a 3rd party library package that requires -Qnew with another one that requires -Qold.

You can learn more about the other flags values that change / warn-about the behavior of division by looking at the python man page.

For full details on division changes read: PEP 238 -- Changing the Division Operator

Ancestor answered 7/1, 2014 at 18:33 Comment(0)
S
2
from operator import truediv

c = truediv(a, b)
Scarberry answered 18/9, 2015 at 10:4 Comment(2)
That's not ideal, though, since it doesn't work in the case where a is an int and b is a float. A better solution along the same lines is to do from operator import truediv and then use truediv(a, b).Histamine
Yeah you're right. I was assuming both integers as this is the only time when the division ops differ but you really want a general solution. I didn't actually know you could import the operator or that it doesn't work at all for float divisors. Answer edited.Scarberry
E
-1
from operator import truediv

c = truediv(a, b)

where a is dividend and b is the divisor. This function is handy when quotient after division of two integers is a float.

Endogenous answered 8/1, 2016 at 5:23 Comment(1)
This was already covered by other answers.Rambort

© 2022 - 2024 — McMap. All rights reserved.