-Wfloat-equal and comparison to zero

Marc Glisse marc.glisse@inria.fr
Tue Nov 12 17:52:00 GMT 2024


On Tue, 12 Nov 2024, David Brown via Gcc wrote:

> On 12/11/2024 15:29, Sad Clouds via Gcc wrote:
>> On Mon, 11 Nov 2024 21:14:43 +0000 (UTC)
>> Joseph Myers <josmyers@redhat.com> wrote:
>> 
>>> I don't think this has anything to do with whether one operand of the
>>> comparison is a constant.  It's still the case when comparing with 0.0
>>> that it's OK if your algorithm is designed such that the other operand is
>>> exact, and questionable if it is an approximation.
>> 
>> Division by 0.0 is somewhat undefined, so should be avoided. One way of
>> checking it is with the equality operator. So whether one of the
>> operands is exact or approximation is irrelevant, since we may only be
>> interested in preventing division by 0.0.
>> 
>
> I've never really understood the preoccupation with division by 0. Under what 
> circumstances would you have code that :
>
> a) Produced a value "x" that might be /exactly/ zero.
>
> b) Divide something by that "x".
>
> c) Are not using full IEEE floating point support with NaNs, infinities, 
> etc., and checks for those after the calculations are done.
>
> d) Would be perfectly happy with "x" having the value 2.225e-307 (or perhaps 
> a little larger) and doing the division with that.
>
> ?

"Randomly" checking gcc's source code, I see in 
libstdc++-v3/include/bits/random.tcc for normal_distribution

             result_type __x, __y, __r2;
             do
               {
                 __x = result_type(2.0) * __aurng() - 1.0;
                 __y = result_type(2.0) * __aurng() - 1.0;
                 __r2 = __x * __x + __y * __y;
               }
             while (__r2 > 1.0 || __r2 == 0.0);

             const result_type __mult = std::sqrt(-2 * std::log(__r2) / __r2);

__r2 could be 0 (a) and we divide by it (b) without checking for 
infinity/nan afterwards (c). However, we can't have (d) (at least for 
usual types, I didn't think about float8_t or other recent mini-floats) 
because __x is computed as 2*thing-1 and thus if it isn't exactly 0 it has 
to be at least epsilon (i.e. far from 0).

(I am surprised there aren't more casts to result_type in this code, for 
float it still uses double a lot)

-- 
Marc Glisse


More information about the Gcc mailing list