Am Fr., 17. Nov. 2023 um 18:31 Uhr schrieb Jonathan Wakely <jwak...@redhat.com>:
>
> On Fri, 17 Nov 2023 at 17:01, Daniel Krügler <daniel.krueg...@gmail.com> 
> wrote:
> >
[..]
> > > +
> > > +namespace std _GLIBCXX_VISIBILITY(default)
> > > +{
> > > +_GLIBCXX_BEGIN_NAMESPACE_VERSION
> > > +
> > > +  /// Add two integers, with saturation in case of overflow.
> > > +  template<typename _Tp> requires __is_standard_integer<_Tp>::value
> > > +    constexpr _Tp
> > > +    add_sat(_Tp __x, _Tp __y) noexcept
> > > +    {
> > > +      _Tp __z;
> > > +      if (!__builtin_add_overflow(__x, __y, &__z))
> > > +       return __z;
> > > +      if constexpr (is_unsigned_v<_Tp>)
> > > +       return __gnu_cxx::__int_traits<_Tp>::__max;
> > > +      else if (__x < 0)
> > > +       return __gnu_cxx::__int_traits<_Tp>::__min;
> >
> > My apologies, but why does the sign of x decide the direction of the
> > result, shouldn't that be the sign of the returned value of z?
>
> z is incorrect at this point, it only has the correct value if no
> overflow occurred. But we know that an overflow occurred because the
> built-in returned true.
>
> We need to determine whether the overflow was positive, i.e. greater
> than numeric_limits<T>::max(), or negative, i.e. lower than
> numeric_limits<T>::min(). For unsigned types, it must have been a
> positive overflow, because neither value is negative so that's easy.
>
> If x is negative, then there is no possible y that can cause a
> positive overflow. If we consider Tp==int, then the maximum y is
> INT_MAX, so if x is negative, x+INT_MAX < INT_MAX. So if x is
> negative, we must have had a negative overflow, and so the result
> saturates to INT_MIN.
>
> If x is positive, there is no possible y that can cause a negative
> overflow. The minimum y is INT_MIN, and so if x is positive, x +
> INT_MIN > INT_MIN. So if x is positive, we must have had a positive
> overflow.
>
> (And x can't be zero, because 0+y would not overflow).

Ah right, thanks.

- Daniel

Reply via email to