0

Verison 2.6.5 if it helps. So, I'm doing some stuff in django and grabbing a value from a Floatfield. And comparing it to another floatfield. Let's call these 2 X and Y. X eventually ends up as 35.0 when I run it. Y eventually ends up as 35.0 when I run it.

35.0 > 35.0 # False, ok no worries
X > Y # True, why?
round(X) > round(Y) # False, ok looks like i have to round it

I know float has issues during calculation but in this case, the values for my two variables were displayed as 35.0 so I thought they actually were 35.0. Does this mean python might not show some information behind the float object? I know this is a common question but if it were actually 35.000000001 or something, does python not display that entire value?

Edit: OK, finally read through this. Floating point life problems solved for me now lol. http://docs.python.org/2/tutorial/floatingpoint.html

dtc
  • 1,774
  • 2
  • 21
  • 44
  • http://stackoverflow.com/questions/16551128/python-float-rounding-errors/16551150 – Joran Beasley May 15 '13 at 01:02
  • so actually, i have another question. i know that would happen but python does not display it? The 35.0 actually means something like 35.000000000001? – dtc May 15 '13 at 01:04
  • basically ... floating points are imprecise – Joran Beasley May 15 '13 at 01:06
  • so floating points are imprecise and sometimes, python won't even display that imprecision. because im getting 35.0 and 35.0 out of x and y. thanks – dtc May 15 '13 at 01:12
  • @JoranBeasley: Why not? `print 35.000000000001` prints `35.0`, even though `35.000000000001 == 35.0` is `False`. – abarnert May 15 '13 at 01:18
  • This is almost certainly a dup of a question about how (different versions of) Python handles rounding of floats in `str` and `repr`… but it's not a dup of a question about floating point accuracy in general. – abarnert May 15 '13 at 01:19
  • [Are repr and str always identical on Pythons builtin numeric types](http://stackoverflow.com/questions/13471581/are-repr-and-str-always-identical-on-pythons-builtin-numeric-types) is at least related. – abarnert May 15 '13 at 01:22
  • @abarnert dang lots of feet in mouth moments for me today :P – Joran Beasley May 15 '13 at 01:53

2 Answers2

2

Python sometimes rounds off floating point values when printing/representing them,* but does not do so while comparing them.

Try this:

'{:.17f} {:.17f}'.format(X, Y)

(Since floats have just over 17 significant digits of precision, and your number is in the range [10, 100), printing 17 digits should be enough to see all of the details that exist. But if you're not sure how to calculate it, just toss on some extra digits: {:.64f} is perfectly legal.)

Alternatively, you could convert them to Decimal objects with a high-enough precision to represent the difference, or many other things.

Or, most simply, X > Y is a good test for whether X is greater than Y, if that's all you actually want to know.


For real-life code, if you want to know if two float values that resulted from two different computations are "the same", you can't do that. Ideally, you need to do proper error analysis. Failing that, an epsilon calculation (abs(X-Y) < EPSILON if you care about a fixed scale, or something like abs((X-Y) / (X+Y)) < EPSILON if you have no idea what the scale might be) is often good enough. But X == Y is never good enough.


* The details differ between different Python versions. For example, try this:

>>> str(1.000000000000001), repr(1.000000000000001)

In Python 2.7, you will get:

'1.0', '1.000000000000001'

But in Python 3.3:

'1.000000000000001', '1.000000000000001'
abarnert
  • 354,177
  • 51
  • 601
  • 671
0

Apart from simple tests against known-exact literals like 0, do not do simple comparisons between floats.

Always subtract and test to see of the absolute value of the difference is below epsilon. If it is, treat the two floats as equal. If the difference is greater than epsilon, use its sign to determine which is greater than the other.

Mark Reed
  • 91,912
  • 16
  • 138
  • 175
  • ok thanks, doing X-Y helped me. When I displayed X and Y, it didn't show me anything past the first decimal. – dtc May 15 '13 at 01:15