X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavutil%2Fsoftfloat.h;h=7488753d646bacd42611515d5fab32804d254905;hb=b40e43c5c40158c2d9490fb0db1109a5387ff8d5;hp=00ff4a1db1bcb11b034ffc6f8ee0b9ebf4bb134c;hpb=564eabeebb1e4239d0ff19a5a93ff9757ebbec70;p=ffmpeg diff --git a/libavutil/softfloat.h b/libavutil/softfloat.h index 00ff4a1db1b..7488753d646 100644 --- a/libavutil/softfloat.h +++ b/libavutil/softfloat.h @@ -36,7 +36,7 @@ typedef struct SoftFloat{ int32_t exp; }SoftFloat; -static const SoftFloat FLOAT_0 = { 0, 0}; +static const SoftFloat FLOAT_0 = { 0, MIN_EXP}; static const SoftFloat FLOAT_05 = { 0x20000000, 0}; static const SoftFloat FLOAT_1 = { 0x20000000, 1}; static const SoftFloat FLOAT_EPSILON = { 0x29F16B12, -16}; @@ -90,7 +90,7 @@ static inline av_const SoftFloat av_normalize1_sf(SoftFloat a){ } /** - * @return Will not be more denormalized than a+b. So if either input is + * @return Will not be more denormalized than a*b. So if either input is * normalized, then the output will not be worse then the other input. * If both are normalized, then the output will be normalized. */ @@ -98,7 +98,10 @@ static inline av_const SoftFloat av_mul_sf(SoftFloat a, SoftFloat b){ a.exp += b.exp; av_assert2((int32_t)((a.mant * (int64_t)b.mant) >> ONE_BITS) == (a.mant * (int64_t)b.mant) >> ONE_BITS); a.mant = (a.mant * (int64_t)b.mant) >> ONE_BITS; - return av_normalize1_sf((SoftFloat){a.mant, a.exp - 1}); + a = av_normalize1_sf((SoftFloat){a.mant, a.exp - 1}); + if (!a.mant || a.exp < MIN_EXP) + return FLOAT_0; + return a; } /** @@ -108,20 +111,27 @@ static inline av_const SoftFloat av_mul_sf(SoftFloat a, SoftFloat b){ static inline av_const SoftFloat av_div_sf(SoftFloat a, SoftFloat b){ a.exp -= b.exp; a.mant = ((int64_t)a.mant<<(ONE_BITS+1)) / b.mant; - return av_normalize1_sf(a); + a = av_normalize1_sf(a); + if (!a.mant || a.exp < MIN_EXP) + return FLOAT_0; + return a; } static inline av_const int av_cmp_sf(SoftFloat a, SoftFloat b){ int t= a.exp - b.exp; - if(t<0) return (a.mant >> (-t)) - b.mant ; - else return a.mant - (b.mant >> t); + if (t <-31) return - b.mant ; + else if (t < 0) return (a.mant >> (-t)) - b.mant ; + else if (t < 32) return a.mant - (b.mant >> t); + else return a.mant ; } static inline av_const int av_gt_sf(SoftFloat a, SoftFloat b) { int t= a.exp - b.exp; - if(t<0) return (a.mant >> (-t)) > b.mant ; - else return a.mant > (b.mant >> t); + if (t <-31) return 0 > b.mant ; + else if (t < 0) return (a.mant >> (-t)) > b.mant ; + else if (t < 32) return a.mant > (b.mant >> t); + else return a.mant > 0 ; } static inline av_const SoftFloat av_add_sf(SoftFloat a, SoftFloat b){ @@ -143,7 +153,12 @@ static inline av_const SoftFloat av_sub_sf(SoftFloat a, SoftFloat b){ * @returns a SoftFloat with value v * 2^frac_bits */ static inline av_const SoftFloat av_int2sf(int v, int frac_bits){ - return av_normalize_sf((SoftFloat){v, ONE_BITS + 1 - frac_bits}); + int exp_offset = 0; + if(v == INT_MIN){ + exp_offset = 1; + v>>=1; + } + return av_normalize_sf(av_normalize1_sf((SoftFloat){v, ONE_BITS + 1 - frac_bits + exp_offset})); } /** @@ -163,7 +178,9 @@ static av_always_inline SoftFloat av_sqrt_sf(SoftFloat val) int tabIndex, rem; if (val.mant == 0) - val.exp = 0; + val.exp = MIN_EXP; + else if (val.mant < 0) + abort(); else { tabIndex = (val.mant - 0x20000000) >> 20;