[FFmpeg-devel] [PATCH 0/2] first steps to resolving float to int undefined behavior

Ronald S. Bultje rsbultje at gmail.com
Mon Nov 2 00:18:02 CET 2015


Hi,

On Sun, Nov 1, 2015 at 6:15 PM, Ganesh Ajjanagadde <gajjanagadde at gmail.com>
wrote:

> On Sun, Nov 1, 2015 at 6:12 PM, Ronald S. Bultje <rsbultje at gmail.com>
> wrote:
> > Hi,
> >
> > On Sun, Nov 1, 2015 at 1:03 PM, Ganesh Ajjanagadde <
> gajjanagadde at gmail.com>
> > wrote:
> >>
> >> Floating point to integer conversion is well defined when the float lies
> >> within
> >> the representation bounds of the integer after discarding the fractional
> >> part.
> >> However, in other cases, unfortunately the standard leaves it undefined.
> >> In particular, assuming that it saturates in a sane way is a dangerous
> >> assumption.
> >>
> >> In light of recent events, I would not have bothered if this was a
> merely
> >> theoretical
> >> issue, and that common environments saturate correctly. Sadly, x86 (for
> >> example)
> >> converts casts to a cvttsd2si instruction which saturates numbers >
> >> INT64_MAX to
> >> INT64_MIN. This is mathematically completely bogus.
> >>
> http://blog.frama-c.com/index.php?post/2013/10/09/Overflow-float-integer
> >> gives
> >> a nice overview of the issue.
> >>
> >> 1/2 adds an av_clipd64 API for this purpose to clip a float to an
> integral
> >> range.
> >> Obviously it will be slower than a cvttsd2si, but there is no option if
> >> one wants
> >> safe and well-defined behavior. Of course, if one knows a priori that a
> >> float
> >> lives in the integral type's range, then there is no issue. Safe
> speedups
> >> are
> >> entirely possible, but API should be finalized first IMHO.
> >> Most common anticipated usages are clipping to [INT64_MIN, INT64_MAX] or
> >> [INT_MIN, INT_MAX].
> >> I have given some thought as to whether a separate av_clipd32 API (for
> >> example)
> >> is necessary. It seems to me to not be the case, since an IEEE-754
> double
> >> is
> >> guaranteed to represent exactly integers up to ~ 2^53.
> >> Similarly, av_clipf64 and the like also seem unnecessary, since a double
> >> is guaranteed
> >> to represent all the values a float does. Such an API may be useful for
> >> performance
> >> though; I do not know how/what float to double conversions entail and at
> >> the
> >> moment ignore such complications.
> >>
> >> 1/2 also accordingly documents av_clipd64.
> >
> >
> > So, is this a bug in llrint, or is this a failure to use llrint, or is
> this
> > different from llrint? It sounds to me that llrint should be used, not
> our
> > own alternative.
>
> Not a bug, just a standard "undefined behavior" cop-out from the
> standards committee. We need to roll our own: all standard functions
> cop out when it does not fit in the integer range, and Intel (and
> others) have wonderfully exploited the cop-out: see e.g the link I
> gave and my other reply.


So how are we going to define "correct" behaviour? Let's take your
INT64_MAX + 100 example. INT64_MAX is nowhere near the correct answer. Now
what?

Ronald


More information about the ffmpeg-devel mailing list