lmi
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [lmi] Shouldn't std::max() and std::min() be commutative?


From: Greg Chicares
Subject: Re: [lmi] Shouldn't std::max() and std::min() be commutative?
Date: Sat, 27 Feb 2021 16:52:27 +0000
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.4.0

On 2/27/21 3:32 PM, Vadim Zeitlin wrote:
> On Sat, 27 Feb 2021 13:13:47 +0000 Greg Chicares <gchicares@sbcglobal.net> 
> wrote:
> 
> GC> Surely it is possible to implement std::max() and std::min() as
> GC> commutative operations [below]

[...but the C++ standard actually forbids that for signed zeros...]

>  I hoped to provide a simple solution to the problem by advising to use
> std::f{min,max} instead of std::{min,max}, as these functions are supposed
> to behave exactly as you'd expect them to.

[...snip fascinating analysis...]

>  Note that I've been careful to use "unexpected" rather than "incorrect"
> results everywhere because these functions are _not_ required to
> distinguish between +0 and -0. For example,
> https://en.cppreference.com/w/c/numeric/math/fmax says:
> 
>> This function is not required to be sensitive to the sign of zero,
>> although some implementations additionally enforce that if one argument
>> is +0 and the other is -0, then +0 is returned. 
> 
> Similarly, a footnote in F.10.9.2 of C11 says
> 
>> Ideally, fmax would be sensitive to the sign of zero, for example
>> fmax(-0.0, +0.0) would return +0; however, implementation in software
>> might be impractical.

I embrace that ideal, and am very glad to hear that at least some people
on the C committee do, too (I didn't know about fmax() until now, though
it was in C99).

I wonder how they concluded that this "might be impractical". Given
signbit(), it's easily done, and a contemporary compiler should optimize
at least as well as if we wrote an explicit C++ "unlikely" attribute here:

        if(0.0 == lhs && 0.0 == rhs) [[unlikely]]
            return std::signbit(rhs) < std::signbit(lhs);
        else
            return lhs < rhs;

so efficiency shouldn't suffer much. And if efficiency were a paramount
concern, C runtime library implementations wouldn't have all that extra
code to deal with special cases.

Maybe they know of some hardware that has signed zeros but doesn't
actually implement IEEE754; but in that case they could at least have
mandated the ideal behavior iff
  #pragma STDC FENV_ACCESS ON
is set.

>  So, to summarize, the behaviour of f{min,max}() is a QoI issue and,
> unfortunately, the only compiler dealing with it satisfactorily is MSVC.
> And this means that there is no standard library function that would
> reliably compute min(0,-0) as being -0 etc and that if such a function is
> really needed in lmi, we have no choice but to write our own.

Thanks, though this saddens me.

>  It's not really clear to me if we actually do need this function or if
> this was just an oddity you've noticed and decided to investigate.

Exactly. I wrote FnMax originally as:
  return ((a < b) ? b : a); // commit e6010c23bb
and then, having checked libstdc++'s std::max() as an afterthought,
amended that to:
  if(a < b) return b; else return a; // commit ecd20b107c
although I've no idea why they chose one over the other (I thought of
the classic double-evaluation problem with a MAX() macro, but they
aren't writing a macro). Then I pondered what other imperfections
might lurk here, and immediately thought of signed zeros.

> I live
> in superstitious horror of negative zeroes, NaNs and other strange FP
> beasts, so I'd prefer to avoid them entirely, if possibly, rather than
> relying on getting the expected results when using them,

It's generally preferable to avoid producing them, but negative zeros
in particular can arise by accident (we've seen them in lmi PDFs).
Authors of library code (like PETE extensions) should worry about
them so that no one else has to.

> but I could be
> missing some reason for which they're actually required in lmi, of course.

They're not required. When we see them, we have the same reaction
as I. I. Rabi when confronted with muons ("Who ordered that?"),
though, unlike Rabi, we then suppress them.

>  Please let me know if you think there is anything worth investigating
> further here,

No, thanks, you've answered all my questions.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]