How to efficiently compare the sign of two floating-point values while handling negative zeros
Posted
by François Beaune
on Stack Overflow
See other posts from Stack Overflow
or by François Beaune
Published on 2010-05-27T15:47:23Z
Indexed on
2010/05/27
15:51 UTC
Read the original article
Hit count: 272
Given two floating-point numbers, I'm looking for an efficient way to check if they have the same sign, given that if any of the two values is zero (+0.0 or -0.0), they should be considered to have the same sign.
For instance,
- SameSign(1.0, 2.0) should return true
- SameSign(-1.0, -2.0) should return true
- SameSign(-1.0, 2.0) should return false
- SameSign(0.0, 1.0) should return true
- SameSign(0.0, -1.0) should return true
- SameSign(-0.0, 1.0) should return true
- SameSign(-0.0, -1.0) should return true
A naive but correct implementation of SameSign
in C++ would be:
bool SameSign(float a, float b)
{
if (fabs(a) == 0.0f || fabs(b) == 0.0f)
return true;
return (a >= 0.0f) == (b >= 0.0f);
}
Assuming the IEEE floating-point model, here's a variant of SameSign
that compiles to branchless code (at least with with Visual C++ 2008):
bool SameSign(float a, float b)
{
int ia = binary_cast<int>(a);
int ib = binary_cast<int>(b);
int az = (ia & 0x7FFFFFFF) == 0;
int bz = (ib & 0x7FFFFFFF) == 0;
int ab = (ia ^ ib) >= 0;
return (az | bz | ab) != 0;
}
with binary_cast
defined as follow:
template <typename Target, typename Source>
inline Target binary_cast(Source s)
{
union
{
Source m_source;
Target m_target;
} u;
u.m_source = s;
return u.m_target;
}
I'm looking for two things:
A faster, more efficient implementation of
SameSign
, using bit tricks, FPU tricks or even SSE intrinsics.An efficient extension of
SameSign
to three values.
© Stack Overflow or respective owner