---------------------------------------- > From: steve+comp.lang.pyt...@pearwood.info > Subject: Re: Short-circuit Logic > Date: Thu, 30 May 2013 05:42:17 +0000 > To: python-list@python.org [...] > Here's another way, mathematically equivalent (although not necessarily > equivalent using floating point computations!) which avoids the divide-by- > zero problem: > > abs(a - b) < epsilon*a
That's wrong! If abs(a) < abs(a-b)/epsilon you will break the commutative law. For example: import sys eps = sys.float_info.epsilon def almost_equalSD(a,b): return abs(a-b) < eps*a #special case a=1 b=1/(1-eps) almost_equalSD(a,b) == almost_equalSD(b,a) Returns False. This discussion reminded me of TAOCP and I paid a visit and bring the following functions: #Floating Point Comparison Operations #Knuth, Donald (1981). The Art of Computer Programming. 2nd ed. Vol. 2. p. 218. Addison-Wesley. ISBN 0-201-03822-6. import sys #floating point comparison: u ≺ v(ε) "definitely less than" (definition 21) def fpc_dlt(u,v,eps=sys.float_info.epsilon): au=abs(u) av=abs(v) return (v-u)> (eps*(au if au>av else av)) # v-u> ε*max(|u|,|v|) #floating point comparison: u ~ v(ε) "approximately equal to" (definition 22) def fpc_aeq(u,v,eps=sys.float_info.epsilon): au=abs(u) av=abs(v) return abs(v-u) <= (eps*(au if au>av else av)) # |v-u| <= ε*max(|u|,|v|) #floating point comparison: u ≻ v(ε) "definitely greater than" (definition 23) def fpc_dgt(u,v,eps=sys.float_info.epsilon): au=abs(u) av=abs(v) return (u-v)> (eps*(au if au>av else av)) # u-v> ε*max(|u|,|v|) #floating point comparison: u ≈ v(ε) "essentially equal to" (definition 24) def fpc_eeq(u,v,eps=sys.float_info.epsilon): au=abs(u) av=abs(v) return abs(v-u) <= (eps*(au if au<av else av)) # |v-u| <= ε*min(|u|,|v|) I've tried to make it look a bit pythonic. Please let me know if it can be improved. ;) So, if you try the following you get the correct answer: #special case a=1 b=1/(1-eps) fpc_aeq(a,b) == fpc_aeq(b,a) > > Whichever method you choose, there are gotchas to watch out for. > >> http://xkcd.com/1047/ > > Nice! > > > -- > Steven > -- > http://mail.python.org/mailman/listinfo/python-list > -- http://mail.python.org/mailman/listinfo/python-list