Hi Jonathan, > On 12/03/19 23:04 +0000, Jonathan Wakely wrote: >>On 12/03/19 22:49 +0000, Joseph Myers wrote: >>>On Tue, 5 Mar 2019, Jonathan Wakely wrote: >>> >>>>The midpoint and lerp functions for floating point types come straight >>>>from the P0811R3 proposal, with no attempt at optimization. >>> >>>I don't know whether P0811R3 states different requirements from the public >>>P0811R2, but the implementation of midpoint using isnormal does *not* >>>satisfy "at most one inexact operation occurs" and is *not* correctly >>>rounded, contrary to the claims made in P0811R2. >> >>I did wonder how the implementation in the paper was meant to meet the >>stated requirements, but I didn't wonder too hard. >> >>>Consider e.g. midpoint(DBL_MIN + DBL_TRUE_MIN, DBL_MIN + DBL_TRUE_MIN). >>>The value DBL_MIN + DBL_TRUE_MIN is normal, but dividing it by 2 is >>>inexact (and so that midpoint implementation would produce DBL_MIN as >>>result, so failing to satisfy midpoint(x, x) == x). >>> >>>Replacing isnormal(x) by something like isgreaterequal(fabs(x), MIN*2) >>>would avoid those inexact divisions, but there would still be spurious >>>overflows in non-default rounding modes for e.g. midpoint(DBL_MAX, >>>DBL_TRUE_MIN) in FE_UPWARD mode, so failing "No overflow occurs" if that's >>>meant to apply in all rounding modes. >> >>Thanks for this review, and the useful cases to test. Ed is working on >>adding some more tests, so maybe he can also look at improving the >>code :-) > > I've committed r272616 to make this case work. This is the proposal > author's most recent suggestion for the implementation. > > Tested x86_64-linux, committed to trunk.
the 26_numerics/midpoint/floating.cc test now FAILs on Solaris (sparc and x86, 32 and 64-bit): +FAIL: 26_numerics/midpoint/floating.cc (test for excess errors) +UNRESOLVED: 26_numerics/midpoint/floating.cc compilation failed to produce executable Excess errors: /vol/gcc/src/hg/trunk/local/libstdc++-v3/testsuite/26_numerics/midpoint/floating.cc:65: error: non-constant condition for static assertion /vol/gcc/src/hg/trunk/local/libstdc++-v3/testsuite/26_numerics/midpoint/floating.cc:65: error: 'constexpr std::enable_if_t<__and_v<std::is_arithmetic<_Tp>, std::is_same<typename std::remove_cv< <template-parameter-1-1> >::type, _Tp>, std::__not_<std::is_same<_Tp, bool> > >, _Tp> std::midpoint(_Tp, _Tp) [with _Tp = double; std::enable_if_t<__and_v<std::is_arithmetic<_Tp>, std::is_same<typename std::remove_cv< <template-parameter-1-1> >::type, _Tp>, std::__not_<std::is_same<_Tp, bool> > >, _Tp> = double]' called in a constant expression /var/gcc/regression/trunk/11-gcc/build/i386-pc-solaris2.11/libstdc++-v3/include/numeric:199: error: call to non-'constexpr' function 'double std::abs(double)' /vol/gcc/src/hg/trunk/local/libstdc++-v3/testsuite/26_numerics/midpoint/floating.cc:68: error: non-constant condition for static assertion /vol/gcc/src/hg/trunk/local/libstdc++-v3/testsuite/26_numerics/midpoint/floating.cc:68: error: 'constexpr std::enable_if_t<__and_v<std::is_arithmetic<_Tp>, std::is_same<typename std::remove_cv< <template-parameter-1-1> >::type, _Tp>, std::__not_<std::is_same<_Tp, bool> > >, _Tp> std::midpoint(_Tp, _Tp) [with _Tp = float; std::enable_if_t<__and_v<std::is_arithmetic<_Tp>, std::is_same<typename std::remove_cv< <template-parameter-1-1> >::type, _Tp>, std::__not_<std::is_same<_Tp, bool> > >, _Tp> = float]' called in a constant expression /var/gcc/regression/trunk/11-gcc/build/i386-pc-solaris2.11/libstdc++-v3/include/numeric:199: error: call to non-'constexpr' function 'float std::abs(float)' /vol/gcc/src/hg/trunk/local/libstdc++-v3/testsuite/26_numerics/midpoint/floating.cc:71: error: non-constant condition for static assertion /vol/gcc/src/hg/trunk/local/libstdc++-v3/testsuite/26_numerics/midpoint/floating.cc:71: error: 'constexpr std::enable_if_t<__and_v<std::is_arithmetic<_Tp>, std::is_same<typename std::remove_cv< <template-parameter-1-1> >::type, _Tp>, std::__not_<std::is_same<_Tp, bool> > >, _Tp> std::midpoint(_Tp, _Tp) [with _Tp = long double; std::enable_if_t<__and_v<std::is_arithmetic<_Tp>, std::is_same<typename std::remove_cv< <template-parameter-1-1> >::type, _Tp>, std::__not_<std::is_same<_Tp, bool> > >, _Tp> = long double]' called in a constant expression /var/gcc/regression/trunk/11-gcc/build/i386-pc-solaris2.11/libstdc++-v3/include/numeric:199: error: call to non-'constexpr' function 'long double std::abs(long double)' Rainer -- ----------------------------------------------------------------------------- Rainer Orth, Center for Biotechnology, Bielefeld University