7 Replies - 1151 Views - Last Post: 19 November 2012 - 04:17 PM Rate Topic: -----

#1 jhar131  Icon User is offline

  • D.I.C Head

Reputation: 2
  • View blog
  • Posts: 149
  • Joined: 03-February 10

Error with floating point arithmetic.

Posted 18 November 2012 - 10:20 PM

Hello all.

I'm trying to read data from multiple files, check for differences, and then see if the differences are within a given tolerance. At the moment, I'm loading the data from the file into an object, one field of which I am casting as a float, like so:
        self.data = float(data)



Now, if there are similarities between files, I want to see if the data is the same, or if not the same, at least within a given tolerance of one another. So if there's a match, I take the absolute value of the differences between the two.

diff = abs(datum1.getData() - datum2.getData())



So far so good, and when I print the individual parts out the math seems good so far; however, when I then make the comparison against the user provided tolerance, the tolerance is always computed as the larger number. I can provide a tolerance of 0.0, and the program will print:

0.0 > 2.68188167066e-05



Any ideas on what's happening here? Is it just a loss of precision as my numbers are so small? Suggestions? I can provide more of / all of the code if you like, but it didn't seem necessary; simple printlining reveals that the data is true.

Is This A Good Question/Topic? 0
  • +

Replies To: Error with floating point arithmetic.

#2 jon.kiparsky  Icon User is online

  • Pancakes!
  • member icon


Reputation: 7293
  • View blog
  • Posts: 12,125
  • Joined: 19-March 11

Re: Error with floating point arithmetic.

Posted 18 November 2012 - 10:27 PM

So my interpreter does not show this error:

>>> 0.0 > 2.68188167066e-05
False
>>> 



So I'd like to see your code, perhaps there's some subtle bug in it.
Was This Post Helpful? 1
  • +
  • -

#3 Python_4_President  Icon User is offline

  • D.I.C Regular

Reputation: 53
  • View blog
  • Posts: 321
  • Joined: 13-August 11

Re: Error with floating point arithmetic.

Posted 18 November 2012 - 11:58 PM

The code would definitely help, but, as it turns out, str(0.0) > 2.0 appears to be True.

>>> str(0.0) > 2.011324
True



Make sure you're not comparing strings to floats.

This post has been edited by Python_4_President: 18 November 2012 - 11:58 PM

Was This Post Helpful? 1
  • +
  • -

#4 jon.kiparsky  Icon User is online

  • Pancakes!
  • member icon


Reputation: 7293
  • View blog
  • Posts: 12,125
  • Joined: 19-March 11

Re: Error with floating point arithmetic.

Posted 19 November 2012 - 12:30 AM

That's basically due to python's ordering of mixed types. Numbers sort before characters. And functions sort between them:
>>> def foo():
...     print "foo"
... 
>>> l = list((1, "asdf", foo))
>>> l.sort()
>>> l
[1, <function foo at 0x1004a22a8>, 'asdf']


(and types sort after strings...)

But yes, the point is there's obviously some way you're getting this effect, and it'll be easier to find it if we can see the code.
Was This Post Helpful? 1
  • +
  • -

#5 jhar131  Icon User is offline

  • D.I.C Head

Reputation: 2
  • View blog
  • Posts: 149
  • Joined: 03-February 10

Re: Error with floating point arithmetic.

Posted 19 November 2012 - 08:12 AM

First off, thank you both for the responses. Repped.

Alright, since it's a rather large script, I'll just add what I think is relevant and if you want to see more just let me know.

First, I get the directories and tolerance from the user:
dir1=sys.argv[1]
dir2=sys.argv[2]
tolerance=sys.argv[3]




Then, if the files are comparable, I load the lines into an object:
class Datum:

    def __init__(self, it, tl, rl, c, ml, ix, iy, iz, time, x, y, z, data):
        self.it = it
        self.tl = tl
        self.rl = rl
        self.c = c
        self.ml = ml
        self.ix = ix
        self.iy = iy
        self.iz = iz
        self.time = time
        self.x = x
        self.y = y
        self.z = z
        self.data = float(data)
        prekey = it + tl + rl + ml + ix + iy + iz
        ixiyiz = ix + iy + iz
        self.xyz = float(ixiyiz)
        self.key = float(prekey)




Finally, if the objects have the same key, I check the data against the tolerance:
def bothCompare(d1,d2,tol,input1,input2):
  for counter, datum1 in enumerate(d1):
    for counter2, datum2 in enumerate(d2):
      if datum1.getKey() == datum2.getKey():
        xyz = datum1.getXYZ()
        tolcheck = float(tol)
        diff = abs(datum1.getData() - datum2.getData())
        printcoord = str(xyz)
        printdiff = str(diff)
        if tol < diff:
          print('FAILED! Tol: '+printtol+' Diff: '+printdiff)


This post has been edited by jhar131: 19 November 2012 - 08:15 AM

Was This Post Helpful? 0
  • +
  • -

#6 jon.kiparsky  Icon User is online

  • Pancakes!
  • member icon


Reputation: 7293
  • View blog
  • Posts: 12,125
  • Joined: 19-March 11

Re: Error with floating point arithmetic.

Posted 19 November 2012 - 08:17 AM

When you call bothCompare(d1,d2,tol,input1,input2), what are you passing as tol?

Specifically, is it actually a float?

Does this problem go away when you change this
if tol < diff:


to this?

if tolcheck < diff:


Was This Post Helpful? 1
  • +
  • -

#7 Python_4_President  Icon User is offline

  • D.I.C Regular

Reputation: 53
  • View blog
  • Posts: 321
  • Joined: 13-August 11

Re: Error with floating point arithmetic.

Posted 19 November 2012 - 08:31 AM

Tol appears to be tolerances. He gets it like so: tolerance=sys.argv[3]
bash-4.1# echo "import sys; print [type(x) for x in sys.argv]" > t.py
bash-4.1# python t.py 3.0 1.2 4.0
[<type 'str'>, <type 'str'>, <type 'str'>, <type 'str'>]





Looks like a case of forgetting to use the new variable (tolcheck). I've done that plenty of times.
Was This Post Helpful? 1
  • +
  • -

#8 jhar131  Icon User is offline

  • D.I.C Head

Reputation: 2
  • View blog
  • Posts: 149
  • Joined: 03-February 10

Re: Error with floating point arithmetic.

Posted 19 November 2012 - 04:17 PM

View Postjon.kiparsky, on 19 November 2012 - 08:17 AM, said:

When you call bothCompare(d1,d2,tol,input1,input2), what are you passing as tol?

Specifically, is it actually a float?




View PostPython_4_President, on 19 November 2012 - 08:31 AM, said:

Looks like a case of forgetting to use the new variable (tolcheck). I've done that plenty of times.



That was it guys. I just forgot to use the new variable. Thank you both for the fresh eyes. Positive rep all around.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1