Short-circuit Logic

Ahmed Abdulshafy abdulshafy at gmail.com
Mon May 27 16:11:28 EDT 2013


On Sunday, May 26, 2013 2:13:47 PM UTC+2, Steven D'Aprano wrote:
> On Sun, 26 May 2013 04:11:56 -0700, Ahmed Abdulshafy wrote:
> 
> 
> 
> > Hi,
> 
> > I'm having a hard time wrapping my head around short-circuit logic
> 
> > that's used by Python, coming from a C/C++ background; so I don't
> 
> > understand why the following condition is written this way!
> 
> > 
> 
> >      if not allow_zero and abs(x) < sys.float_info.epsilon:
> 
> >                 print("zero is not allowed")
> 
> 
> 
> Follow the logic.
> 
> 
> 
> If allow_zero is a true value, then "not allow_zero" is False, and the 
> 
> "and" clause cannot evaluate to true. (False and X is always False.) So 
> 
> print is not called.
> 
> 
> 
> If allow_zero is a false value, then "not allow_zero" is True, and the 
> 
> "and" clause depends on the second argument. (True and X is always X.) So
> 
> abs(x) < sys.float_info.epsilon is tested, and if that is True, print is 
> 
> called.
> 
> 
> 
> By the way, I don't think much of this logic. Values smaller than epsilon 
> 
> are not necessarily zero:
> 
> 
> 
> py> import sys
> 
> py> epsilon = sys.float_info.epsilon
> 
> py> x = epsilon/10000
> 
> py> x == 0
> 
> False
> 
> py> x * 3 == 0
> 
> False
> 
> py> x + epsilon == 0
> 
> False
> 
> py> x + epsilon == epsilon
> 
> False
> 
> 
> 
> The above logic throws away many perfectly good numbers and treats them 
> 
> as zero even though they aren't.
> 
> 
> 
> 
> 
> > The purpose of this snippet is to print the given line when allow_zero
> 
> > is False and x is 0.
> 
> 
> 
> Then the snippet utterly fails at that, since it prints the line for many 
> 
> values of x which can be distinguished from zero. The way to test whether 
> 
> x equals zero is:
> 
> 
> 
> x == 0
> 
> 
> 
> What the above actually tests for is whether x is so small that (1.0+x) 
> 
> cannot be distinguished from 1.0, which is not the same thing. It is also 
> 
> quite arbitrary. Why 1.0? Why not (0.0001+x)? Or (0.00000001+x)? Or 
> 
> (10000.0+x)?
> 
> 
> 
> 
> 
> 
> 
> -- 
> 
> Steven

That may be true for integers, but for floats, testing for equality is not always precise



More information about the Python-list mailing list