[Numpy-discussion] making the distinction between -0.0 and 0.0..
Joe Kington
jkington@wisc....
Tue Sep 29 16:37:55 CDT 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@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@noaa.gov
> _______________________________________________
> NumPy-Discussion mailing list
> NumPy-Discussion@scipy.org
> http://mail.scipy.org/mailman/listinfo/numpy-discussion
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.scipy.org/pipermail/numpy-discussion/attachments/20090929/67b37960/attachment-0001.html
More information about the NumPy-Discussion
mailing list