[Numpy-discussion] making the distinction between -0.0 and 0.0..

Joe Kington jkington at wisc.edu
Tue Sep 29 17:37:55 EDT 2009


I know it's a bit pointless profiling these, but just so I can avoid doing
real work for a bit...

In [1]: import sys, struct, math

In [2]: def comp_struct(x):
   ...:     # Get the first or last byte, depending on endianness
   ...:     # (using '>f' or '<f' loses the signbit for -0.0 in older
python's)
   ...:     i = {'little':-1, 'big':0}[sys.byteorder]
   ...:     return struct.unpack('b', struct.pack('f', x)[i])[0] < 0
   ...:

In [3]: comp_struct(0.00); comp_struct(-0.00)
Out[3]: False
Out[3]: True

In [4]: def comp_string(x):
   ...:     return x.__repr__().startswith('-')
   ...:

In [5]: comp_struct(0.00); comp_struct(-0.00)
Out[5]: False
Out[5]: True

In [6]: def comp_atan(x):
   ....:     if x > 0: return False
   ....:     elif x < 0: return True
   ....:     elif math.atan2(x, -1.0) > 0:
   ....:         return False
   ....:     else:
   ....:        return True
   ....:

In [7]: comp_atan(0.00); comp_atan(-0.00)
Out[7]: False
Out[7]: True

In [8]: %timeit comp_struct(-0.0)
1000000 loops, best of 3: 971 ns per loop

In [9]: %timeit comp_string(-0.0)
1000000 loops, best of 3: 1.43 us per loop

In [10]: %timeit comp_atan(-0.0)
1000000 loops, best of 3: 502 ns per loop

And just to compare to what was just posted:
In [45]: %timeit signbit(-0.0)
1000000 loops, best of 3: 995 ns per loop

So, if speed matters, apparently checking things through atan2 is the
fastest.  (wouldn't have guessed that!)

On the other hand I'm being a bit ridiculous profiling these... Use
whichever is the most readable, I guess.

This is more fun than real work, though!
-Joe

On Tue, Sep 29, 2009 at 4:24 PM, Christopher Barker
<Chris.Barker at noaa.gov>wrote:

> Christian Heimes wrote:
> > How about using atan2()? :)
>
> unless atan2 shortcuts for the easy ones, that doesn't strike me as
> efficient (though with python function call overhead, maybe!).
>
> Anyway, of course, some googling that I should have done in the first
> place, revealed "double.py", from Martin Jansche:
>
> http://symptotic.com/mj/code.html
> (MIT license).
>
>
> double.py provides a full(?) set of IEEE functions for doubles in
> Python. His solution to the problem at hand is:
>
> def signbit(value):
>     """
>     Test whether the sign bit of the given floating-point value is
>     set.  If it is set, this generally means the given value is
>     negative.  However, this is not the same as comparing the value
>     to C{0.0}.  For example:
>
>     >>> NEGATIVE_ZERO < 0.0
>     False
>
>     since negative zero is numerically equal to positive zero.  But
>     the sign bit of negative zero is indeed set:
>
>     >>> signbit(NEGATIVE_ZERO)
>     True
>     >>> signbit(0.0)
>     False
>
>     @type  value: float
>     @param value: a Python (double-precision) float value
>
>     @rtype:  bool
>     @return: C{True} if the sign bit of C{value} is set;
>              C{False} if it is not set.
>     """
>     return (doubleToRawLongBits(value) >> 63) == 1
>
> where:
>
> def doubleToRawLongBits(value):
>     """
>     @type  value: float
>     @param value: a Python (double-precision) float value
>
>     @rtype: long
>     @return: the IEEE 754 bit representation (64 bits as a long integer)
>              of the given double-precision floating-point value.
>     """
>     # pack double into 64 bits, then unpack as long int
>     return _struct.unpack('Q', _struct.pack('d', value))[0]
>
>
> Which is pretty much what I was looking for, though I can't say I've
> profiled the various options at hand!
>
> -Chris
>
>
>
> --
> Christopher Barker, Ph.D.
> Oceanographer
>
> Emergency Response Division
> NOAA/NOS/OR&R            (206) 526-6959   voice
> 7600 Sand Point Way NE   (206) 526-6329   fax
> Seattle, WA  98115       (206) 526-6317   main reception
>
> Chris.Barker at noaa.gov
> _______________________________________________
> NumPy-Discussion mailing list
> NumPy-Discussion at scipy.org
> http://mail.scipy.org/mailman/listinfo/numpy-discussion
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/numpy-discussion/attachments/20090929/67b37960/attachment.html>


More information about the NumPy-Discussion mailing list