Sunday, 2 July 2017

python - How can I force division to be floating point? Division keeps rounding down to 0?


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
>>> 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
>>> 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 "", line 1, in
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

No comments:

Post a Comment

casting - Why wasn&#39;t Tobey Maguire in The Amazing Spider-Man? - Movies &amp; TV

In the Spider-Man franchise, Tobey Maguire is an outstanding performer as a Spider-Man and also reprised his role in the sequels Spider-Man...