[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