Short-circuit Logic
Carlos Nepomuceno
carlosnepomuceno at outlook.com
Thu May 30 17:03:13 EDT 2013
----------------------------------------
> From: steve+comp.lang.python at pearwood.info
> Subject: Re: Short-circuit Logic
> Date: Thu, 30 May 2013 05:42:17 +0000
> To: python-list at 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
More information about the Python-list
mailing list