nerdcortex
nerdcortex

Reputation: 147

Division by 3 in Python

I am new to Python and while experimenting with operators, I came across this:

>>> 7.0 / 3
2.3333333333333335

Shouldn't the result be 2.3333333333333333 or maybe 2.3333333333333334. Why is it rounding the number in such a way?

Also, with regard to floor division in Python 2.7 my results were:

>>> 5 / 2
2
>>> 5 // 2
2
>>> 5.0 / 2
2.5
>>> 5.0 // 2
2.0

So my observation is that floor division returns the integer quotient even in case of floating numbers, while normal division return the decimal value. Is this true?

Upvotes: 3

Views: 1816

Answers (2)

plugwash
plugwash

Reputation: 10514

Shouldn't the result be 2.3333333333333333 or maybe 2.3333333333333334. Why is it rounding the number in such a way?

The key is the number is being rounded twice.

The first rounding is part of the division operation, rounding the number to the nearest double-precision floating point value. This is a binary operation not a decimal one.

The second rounding is part of converting the floating point number to a decimal representation for display. It is possible to represent the exact value of any binary fraction in decimal, but it is usually not desirable as in most applications doing so will simply result in many digits of false-precision. Python instead outputs the shortest decimal approximation that will round-trip to the correct floating point value.

We can better see what is going on by using the Fraction and Decimal types, unlike converting directly to a string converting a floating point number to a Fraction or Decimal will give the exact value. We can also use the Fraction type to determine the error in our calculation.

>>> from fractions import Fraction
>>> from decimal import Decimal
>>> 7.0 / 3
2.3333333333333335
>>> Decimal(7.0 / 3)
Decimal('2.333333333333333481363069950020872056484222412109375')
>>> Fraction(7.0 / 3)
Fraction(5254199565265579, 2251799813685248)
>>> Fraction(7,3) - Fraction(7.0 / 3)
Fraction(-1, 6755399441055744)

The conversion via type Decimal shows us the exact value of the floating point number and demonstrates the many digits of false-precision that typically result from exact conversion of a floating point value to decimal.

The conversion to a Fraction is also interesting, the denominator is 2251799813685248 which is equivalent to 251. This makes perfect sense, a Double precision floating point has 53 effective bits of mantissa and we need two of those for the integral part of the result leaving 51 for the fractional part.

The error in our floating point calculation is 1/6755399441055744 or ⅓ * 2-51. This error is less than half our precision step of 2-51 so the answer was indeed correctly rounded to a double precision floating point value.

Upvotes: 0

farhawa
farhawa

Reputation: 10417

Take a look at this 0.30000000000000004.com

Your language isn't broken, it's doing floating point math. Computers can only natively store integers, so they need some way of representing decimal numbers. This representation comes with some degree of inaccuracy. That's why, more often than not, .1 + .2 != .3.

Upvotes: 3

Related Questions