On Fri, Nov 13, 2015 at 12:10 PM, Ronald S. Bultje <rsbul...@gmail.com> wrote: > Hi Ganesh, > On Nov 13, 2015 12:02 PM, "Ganesh Ajjanagadde" <gajjanaga...@gmail.com> > wrote: >> >> The rationale for this function is reflected in the documentation for >> it, and is copied here: >> >> Clip a double value into the long long amin-amax range. >> This function is needed because conversion of floating point to integers > when >> it does not fit in the integer's representation does not necessarily > saturate >> correctly (usually converted to a cvttsd2si on x86) which saturates > numbers >> > INT64_MAX to INT64_MIN. The standard marks such conversions as undefined >> behavior, allowing this sort of mathematically bogus conversions. This > provides >> a safe alternative that is slower obviously but assures safety and better >> mathematical behavior. >> API: >> @param a value to clip >> @param amin minimum value of the clip range >> @param amax maximum value of the clip range >> @return clipped value >> >> Note that a priori if one can guarantee from the calling side that the >> double is in range, it is safe to simply do an explicit/implicit cast, >> and that will be far faster. However, otherwise this function should be >> used. >> >> avutil minor version is bumped. >> >> Reviewed-by: Ronald S. Bultje <rsbul...@gmail.com> >> Signed-off-by: Ganesh Ajjanagadde <gajjanaga...@gmail.com> >> --- >> libavutil/common.h | 30 ++++++++++++++++++++++++++++++ >> libavutil/version.h | 2 +- >> 2 files changed, 31 insertions(+), 1 deletion(-) >> >> diff --git a/libavutil/common.h b/libavutil/common.h >> index 6f0f582..f4687ab 100644 >> --- a/libavutil/common.h >> +++ b/libavutil/common.h >> @@ -298,6 +298,33 @@ static av_always_inline av_const double > av_clipd_c(double a, double amin, double >> else return a; >> } >> >> +/** >> + * Clip and convert a double value into the long long amin-amax range. >> + * This function is needed because conversion of floating point to > integers when >> + * it does not fit in the integer's representation does not necessarily > saturate >> + * correctly (usually converted to a cvttsd2si on x86) which saturates > numbers >> + * > INT64_MAX to INT64_MIN. The standard marks such conversions as > undefined >> + * behavior, allowing this sort of mathematically bogus conversions. > This provides >> + * a safe alternative that is slower obviously but assures safety and > better >> + * mathematical behavior. >> + * @param a value to clip >> + * @param amin minimum value of the clip range >> + * @param amax maximum value of the clip range >> + * @return clipped value >> + */ >> +static av_always_inline av_const int64_t av_rint64_clip_c(double a, > int64_t amin, int64_t amax) >> +{ >> +#if defined(HAVE_AV_CONFIG_H) && defined(ASSERT_LEVEL) && ASSERT_LEVEL >>= 2 >> + if (amin > amax) abort(); >> +#endif >> + // INT64_MAX+1,INT64_MIN are exactly representable as IEEE doubles >> + if (a >= 9223372036854775808.0 || llrint(a) >= amax) >> + return amax; >> + if (a <= -9223372036854775808.0 || llrint(a) <= amin) >> + return amin; > > Doesn't this allow negative overflows in the max check? I think you need > both overflow checks before the min/max checks. Try the next float val > smaller than int64_min as input with a small amax, eg 0. I bet it returns 0 > instead of amin.
They are needed. As you and others can clearly see, I am quite bad with this stuff. > > Rest looks OK. I'd personally store llrint retval in a variable but let's > assume compiler is clever enough to optimize that out. While refactoring, made sense for me to add a temporary. Unless you want to see an updated patch, will push. > > Ronald > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel