On Thu, Oct 01, 2015 at 05:43:15PM +0200, Michael Matz wrote:
> Hi,
> 
> On Thu, 1 Oct 2015, James Greenhalgh wrote:
> 
> > > >  x * copysign (1.0, y)
> > > > 
> > > >  x ^ (y & (1 << sign_bit_position))
> > > 
> > > Also I think this can only be done for finite and non trapping types. 
> > 
> > That may be well true, I swithered either way and went for no checks, 
> > but I'd happily go back on that and wrap this in something suitable 
> > restrictive if I need to.
> 
> I don't think that's necessary.  copysign (1.0, y) is always 1.0 or -1.0, 
> even with y being a NaN or inf.  Additionally copysign is allowed to not 
> signal even if y is a sNaN.  That leaves only the form of x to doubt.  If 
> x is inf all is well (multiplying by +-1.0 is defined and both sequences 
> get the same result), if x is NaN the result must be a NaN, and it is in 
> both cases.  The catch is that strictly speaking (NaN * -1.0) needs to 
> deliver NaN, not -NaN (operations involving quiet NaNs need to provide 
> one of the input NaNs as result), and here both are not equivalent.  OTOH 
> the sign of NaNs isn't specified, so I think we could reasonably decide to 
> not care about this case (it would have to be checked if the hardware 
> multiplication even follows that rule, otherwise it's moot anyway).

But if x is a sNaN, then the multiplication will throw an exception, while
the transformed operation will not.  So perhaps it should be guarded by
!HONOR_SNANS (TYPE_MODE (type))
?  And sure, somebody should look at why this isn't done in SSE.

        Jakub

Reply via email to