fronthem - 6 months ago 14

Python Question

Let's consider the code below

code:

`#!/usr/bin/env python`

class Foo():

def __init__(self, b):

self.a = 0.0

self.b = b

def count_a(self):

self.a += 0.1

foo = Foo(1)

for i in range(0, 15):

foo.count_a()

print "a =", foo.a, "b =", foo.b, '"a == b" ->', foo.a == foo.b

Output:

`a = 0.2 b = 1 "a == b" -> False`

a = 0.4 b = 1 "a == b" -> False

a = 0.6 b = 1 "a == b" -> False

a = 0.8 b = 1 "a == b" -> False

a = 1.0 b = 1 "a == b" -> True

a = 1.2 b = 1 "a == b" -> False

a = 1.4 b = 1 "a == b" -> False

a = 1.6 b = 1 "a == b" -> False

a = 1.8 b = 1 "a == b" -> False

a = 2.0 b = 1 "a == b" -> False

a = 2.2 b = 1 "a == b" -> False

a = 2.4 b = 1 "a == b" -> False

a = 2.6 b = 1 "a == b" -> False

a = 2.8 b = 1 "a == b" -> False

a = 3.0 b = 1 "a == b" -> False

But if I change code on line

`11`

`foo = Foo(2)`

`a = 0.2 b = 2 "a == b" -> False`

a = 0.4 b = 2 "a == b" -> False

a = 0.6 b = 2 "a == b" -> False

a = 0.8 b = 2 "a == b" -> False

a = 1.0 b = 2 "a == b" -> False

a = 1.2 b = 2 "a == b" -> False

a = 1.4 b = 2 "a == b" -> False

a = 1.6 b = 2 "a == b" -> False

a = 1.8 b = 2 "a == b" -> False

a = 2.0 b = 2 "a == b" -> False *

a = 2.2 b = 2 "a == b" -> False

a = 2.4 b = 2 "a == b" -> False

a = 2.6 b = 2 "a == b" -> False

a = 2.8 b = 2 "a == b" -> False

a = 3.0 b = 2 "a == b" -> False

You will see that the output

`a = 2.0 b = 2 "a == b" -> False`

Answer

This has nothing to do with Object Orientation - it has to do with the way computers represent floating point numbers internally, and rounding errors. http://floating-point-gui.de/basic/

The Python specificity here is the default string representation of floating point numbers, which will round them at less decimal places than the internal representation for pretty printing.

Although, for people needing correct comparisons, respecting the scale of floating point numbers, Python has introduced a nice mechanism with PEP 485, which added the `math.isclose`

function to the standard library.