1

It's not exactly with 1 > 1 but close:

I want to compare two timestamps and do something if time > timestamp evaluates to True. Both variables have the same float in them, as seen in pdb

(Pdb) print time
1396836917.98
(Pdb) print last_timestamp
1396836917.98
(Pdb) if time > last_timestamp: print 'wtf'
wtf

I would expect this to evaluate as False, it seems to be a float problem:

(Pdb) if float(time) > float(last_timestamp): print 'wtf'
wtf

int comparison works fine

(Pdb) if int(time) > int(last_timestamp): print 'wtf'

So I expected a problem with the precision of available bits representing the number

(Pdb) if float(time)*100 > float(last_timestamp)*100: print 'wtf'
wtf

but it still evaluates as True if there are no decimal places left ..

A work around for me right now is

if int(time*100) > int(last_timestamp*100): print 'wtf'

but I'd really love to understand what is going on and how to use the > operator correctly with float..

gletscher
  • 1,132
  • 2
  • 11
  • 18

2 Answers2

3

Which version of Python are you using? print implicitly invokes str, which in older versions of Python can hide differences between distinct floats. Try printing repr(time) and repr(last_timestamp) instead. If the floats are distinct, repr will produce different strings for them.

Tim Peters
  • 67,464
  • 13
  • 126
  • 132
  • `Python 2.7.5+ (default, Feb 27 2014, 19:37:08) [GCC 4.8.1] on linux2 Type "help", "copyright", "credits" or "license" for more information.` I will give `repr()` a shot, but I gather the timestamps as `string` so there shouldn't be a difference .. – gletscher Apr 07 '14 at 03:19
  • Try `repr`. It doesn't matter where the timestamps came from. – Tim Peters Apr 07 '14 at 03:32
0

This sounds like a floating point understanding issue.

Basically except for certain rare numbers floating point numbers do not store numbers exactly, they store a number that is a tiny amount different from the one you think you are seeing. For example (1-0.8 != 0.2).

Here's an email I wrote about Java but virtually all languages have the same behavior:

Try calculating (int)(4.1-0.1) in Java (and anything else using the standard IEE floating point algorithms with truncating integer conversion) and the result you will get is 3.

For some more examples see:

http://ideone.com/ZseOnZ

If you convert the doubles to floats you get a completely different set of values which are wrong but for example (int)(4.2f-0.2f) gives the wrong result.

For SQL you can illustrate the same thing:

        select CONVERT(INTEGER, CONVERT(float, 4.1)-CONVERT(float, 0.1))

This gives a result of 3.

Tim B
  • 40,716
  • 16
  • 83
  • 128