[cfe-dev] [libcxx/test] Floating point comparisons
Howard Hinnant
hhinnant at apple.com
Thu Dec 1 11:11:44 PST 2011
On Dec 1, 2011, at 1:54 PM, Edward Meewis wrote:
> Hi,
>
> I am experimenting with libcxx on FreeBSD and got a lot of asserts on
> floating point comparisons, most notably in
> 'libcxx/test/containers/unord', e.g.:
>
> Assertion failed: (c.load_factor() == (float)c.size()/c.bucket_count()),
> function main, file assign_move.pass.cpp, line 71.
>
> Switching on optimization makes them go away. I'm guessing one of the
> values gets promoted from a float to a double somewhere, which makes the
> comparison fail.
>
> The question is: do the lvalue and rvalue need to be exactly the same? I
> think it would be better to use something like:
>
> assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) <
> FLT_EPSILON);
>
> to sidestep the issue. It also has the benefit of being more
> implementation independent?
Before changing this I'd like to understand the issue, just to make sure we wouldn't be hiding a bug.
load_factor() is computed (in <__hash_table>) as:
_LIBCPP_INLINE_VISIBILITY float load_factor() const _NOEXCEPT
{
size_type __bc = bucket_count();
return __bc != 0 ? (float)size() / __bc : 0.f;
}
which is precisely how the test is computed too. So I currently do not understand the cause of the assert.
And just to head off the discussion that one should never compare floating point with equality: I'm aware of how floating point works. But I also know that it is deterministic, down to the very last bit.
Is there a legal compiler transformation that can make this test fail?
Howard
More information about the cfe-dev
mailing list