Why Does -22/10 return -3 in python. Any pointers regarding this will be helpful for me.
Because it's integer division by default. And integer division is rounded towards minus infinity. Take a look:
>>> -22/10
-3
>>> -22/10.0
-2.2000000000000002
Positive:
>>> 22/10
2
>>> 22/10.0
2.2000000000000002
Regarding the seeming "inaccuracy" of floating point, this is a great article to read: Why are floating point calculations so inaccurate?
Because you're doing an integer division. If you do -22.0/10 instead, you'll get the correct result.
By default, the current versions of Python 2.x (I'm not sure about 3.x) give an integer result for any arithmetic operator when both operands are integers. However, there is a way to change this behaviour.
from __future__ import division
print(22/10)
Outputs
2.2000000000000002
Of course, a simpler way is to simply make one of the operands a float as described by the previous two answers.
PEP 238, "Changing the Division Operator", explains the issues well, I think. In brief: when Python was designed it adopted the "truncating" meaning for /
between integers, simply because most other programming languages did ever since the first FORTRAN compiler was launched in 1957 (all-uppercase language name and all;-). (One widespread language that didn't adopt this meaning, using /
to produce a floating point result and div
for truncation, was Pascal).
In 2001 it was decided that this choice was not optimal (to quote the PEP, "This makes expressions expecting float or complex results error-prone when integers are not expected but possible as inputs"), and to switch to using a new operator //
to request division with truncation, and change the meaning of /
to produce a float result ("true division").
You can explicitly request this behavior by putting the statement
from __future__ import division
at the start of a module (the command-line switch -Q
to the python
interpreter can also control the behavior of division). Missing such an "import from the future" (and command line switch use), Python 2.x, for all values of x, always uses "classic division" (i.e., /
is truncating between int
s).
Python 3, however, always uses "true division" (/
between int
s produces a float
).
Note a curious corollary (in Python 3)...:
>>> from fractions import Fraction
>>> Fraction(1/2)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Library/Frameworks/Python.framework/Versions/3.1/lib/python3.1/fractions.py", line 100, in __new__
raise TypeError("argument should be a string "
TypeError: argument should be a string or a Rational instance
since /
produces a float
, it's not acceptable as the argument to Fraction
(otherwise precision might be silently lost). You must use a string, or pass numerator and denominator as separate arguments:
>>> Fraction(1, 2)
Fraction(1, 2)
>>> Fraction('1/2')
Fraction(1, 2)
gmpy uses a different, more tolerant approach to building mpq
s, its equivalent of Python 3 Fraction
s...:
>>> import gmpy
>>> gmpy.mpq(1/2)
mpq(1,2)
Specifically (see lines 3168 and following in the source), gmpy uses a Stern-Brocot tree to get the "best practical approximation" of the floating point argument as a rational (of course, this can mask a loss of precision).
This happens because the operation of integer division returns the number, which when multiplied by the divisor gives the largest possible integer that is no larger than the number you divided.
This is exactly why 22/10 gives 2: 10*2=20, which is the largest integer multiple of 10 not bigger than 20.
When this goes to the negative, your operation becomes -22/10. Your result is -3. Applying the same logic as in the previous case, we see that 10*-3=-30, which is the largest integer multiple of 10 not bigger than -20.
This is why you get a slightly unexpected answer when dealing with negative numbers.
Hope that helps