2 * Copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
4 * This file is part of FFmpeg.
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 #ifndef AVUTIL_SOFTFLOAT_H
22 #define AVUTIL_SOFTFLOAT_H
28 #include "softfloat_tables.h"
34 typedef struct SoftFloat
{
39 static const SoftFloat FLOAT_0
= { 0, MIN_EXP
}; ///< 0.0
40 static const SoftFloat FLOAT_05
= { 0x20000000, 0}; ///< 0.5
41 static const SoftFloat FLOAT_1
= { 0x20000000, 1}; ///< 1.0
42 static const SoftFloat FLOAT_EPSILON
= { 0x29F16B12, -16}; ///< A small value
43 static const SoftFloat FLOAT_1584893192
= { 0x32B771ED, 1}; ///< 1.584893192 (10^.2)
44 static const SoftFloat FLOAT_100000
= { 0x30D40000, 17}; ///< 100000
45 static const SoftFloat FLOAT_0999999
= { 0x3FFFFBCE, 0}; ///< 0.999999
46 static const SoftFloat FLOAT_MIN
= { 0x20000000, MIN_EXP
};
50 * Convert a SoftFloat to a double precision float.
52 static inline av_const
double av_sf2double(SoftFloat v
) {
54 return ldexp(v
.mant
, v
.exp
);
57 static av_const SoftFloat
av_normalize_sf(SoftFloat a
){
60 while((a
.mant
+ 0x1FFFFFFFU
)<0x3FFFFFFFU
){
65 int s
=ONE_BITS
- av_log2(FFABS(a
.mant
));
79 static inline av_const SoftFloat
av_normalize1_sf(SoftFloat a
){
81 if((int32_t)(a
.mant
+ 0x40000000U
) <= 0){
85 av_assert2(a
.mant
< 0x40000000 && a
.mant
> -0x40000000);
86 av_assert2(a
.exp
<= MAX_EXP
);
89 int t
= a
.mant
+ 0x40000000 < 0;
90 return (SoftFloat
){ a
.mant
>>t
, a
.exp
+t
};
92 int t
= (a
.mant
+ 0x3FFFFFFFU
)>>31;
93 return (SoftFloat
){a
.mant
>>t
, a
.exp
+t
};
98 * @return Will not be more denormalized than a*b. So if either input is
99 * normalized, then the output will not be worse then the other input.
100 * If both are normalized, then the output will be normalized.
102 static inline av_const SoftFloat
av_mul_sf(SoftFloat a
, SoftFloat b
){
104 av_assert2((int32_t)((a
.mant
* (int64_t)b
.mant
) >> ONE_BITS
) == (a
.mant
* (int64_t)b
.mant
) >> ONE_BITS
);
105 a
.mant
= (a
.mant
* (int64_t)b
.mant
) >> ONE_BITS
;
106 a
= av_normalize1_sf((SoftFloat
){a
.mant
, a
.exp
- 1});
107 if (!a
.mant
|| a
.exp
< MIN_EXP
)
113 * b has to be normalized and not zero.
114 * @return Will not be more denormalized than a.
116 static inline av_const SoftFloat
av_div_sf(SoftFloat a
, SoftFloat b
){
117 int64_t temp
= (int64_t)a
.mant
* (1<<(ONE_BITS
+1));
121 while (a
.mant
!= temp
) {
126 a
= av_normalize1_sf(a
);
127 if (!a
.mant
|| a
.exp
< MIN_EXP
)
133 * Compares two SoftFloats.
134 * @returns < 0 if the first is less
135 * > 0 if the first is greater
136 * 0 if they are equal
138 static inline av_const
int av_cmp_sf(SoftFloat a
, SoftFloat b
){
139 int t
= a
.exp
- b
.exp
;
140 if (t
<-31) return - b
.mant
;
141 else if (t
< 0) return (a
.mant
>> (-t
)) - b
.mant
;
142 else if (t
< 32) return a
.mant
- (b
.mant
>> t
);
147 * Compares two SoftFloats.
148 * @returns 1 if a is greater than b, 0 otherwise
150 static inline av_const
int av_gt_sf(SoftFloat a
, SoftFloat b
)
152 int t
= a
.exp
- b
.exp
;
153 if (t
<-31) return 0 > b
.mant
;
154 else if (t
< 0) return (a
.mant
>> (-t
)) > b
.mant
;
155 else if (t
< 32) return a
.mant
> (b
.mant
>> t
);
156 else return a
.mant
> 0 ;
160 * @returns the sum of 2 SoftFloats.
162 static inline av_const SoftFloat
av_add_sf(SoftFloat a
, SoftFloat b
){
163 int t
= a
.exp
- b
.exp
;
164 if (t
<-31) return b
;
165 else if (t
< 0) return av_normalize_sf(av_normalize1_sf((SoftFloat
){ b
.mant
+ (a
.mant
>> (-t
)), b
.exp
}));
166 else if (t
< 32) return av_normalize_sf(av_normalize1_sf((SoftFloat
){ a
.mant
+ (b
.mant
>> t
), a
.exp
}));
171 * @returns the difference of 2 SoftFloats.
173 static inline av_const SoftFloat
av_sub_sf(SoftFloat a
, SoftFloat b
){
174 return av_add_sf(a
, (SoftFloat
){ -b
.mant
, b
.exp
});
177 //FIXME log, exp, pow
180 * Converts a mantisse and exponent to a SoftFloat.
181 * This converts a fixed point value v with frac_bits fractional bits to a
183 * @returns a SoftFloat with value v * 2^-frac_bits
185 static inline av_const SoftFloat
av_int2sf(int v
, int frac_bits
){
187 if(v
<= INT_MIN
+ 1){
191 return av_normalize_sf(av_normalize1_sf((SoftFloat
){v
, ONE_BITS
+ 1 - frac_bits
+ exp_offset
}));
195 * Converts a SoftFloat to an integer.
196 * Rounding is to -inf.
198 static inline av_const
int av_sf2int(SoftFloat v
, int frac_bits
){
199 v
.exp
+= frac_bits
- (ONE_BITS
+ 1);
200 if(v
.exp
>= 0) return v
.mant
<< v
.exp
;
201 else return v
.mant
>>(-v
.exp
);
205 * Rounding-to-nearest used.
207 static av_always_inline SoftFloat
av_sqrt_sf(SoftFloat val
)
213 else if (val
.mant
< 0)
217 tabIndex
= (val
.mant
- 0x20000000) >> 20;
219 rem
= val
.mant
& 0xFFFFF;
220 val
.mant
= (int)(((int64_t)av_sqrttbl_sf
[tabIndex
] * (0x100000 - rem
) +
221 (int64_t)av_sqrttbl_sf
[tabIndex
+ 1] * rem
+
223 val
.mant
= (int)(((int64_t)av_sqr_exp_multbl_sf
[val
.exp
& 1] * val
.mant
+
226 if (val
.mant
< 0x40000000)
231 val
.exp
= (val
.exp
>> 1) + 1;
238 * Rounding-to-nearest used.
240 * @param a angle in units of (1ULL<<30)/M_PI radians
241 * @param s pointer to where sine in units of (1<<30) is returned
242 * @param c pointer to where cosine in units of (1<<30) is returned
244 static av_unused
void av_sincos_sf(int a
, int *s
, int *c
)
251 sign
= (int32_t)((unsigned)idx
<< 27) >> 31;
252 cv
= av_costbl_1_sf
[idx
& 0xf];
253 cv
= (cv
^ sign
) - sign
;
256 sign
= (int32_t)((unsigned)idx
<< 27) >> 31;
257 sv
= av_costbl_1_sf
[idx
& 0xf];
258 sv
= (sv
^ sign
) - sign
;
261 ct
= av_costbl_2_sf
[idx
& 0x1f];
262 st
= av_sintbl_2_sf
[idx
& 0x1f];
264 idx
= (int)(((int64_t)cv
* ct
- (int64_t)sv
* st
+ 0x20000000) >> 30);
266 sv
= (int)(((int64_t)cv
* st
+ (int64_t)sv
* ct
+ 0x20000000) >> 30);
271 ct
= av_costbl_3_sf
[idx
& 0x1f];
272 st
= av_sintbl_3_sf
[idx
& 0x1f];
274 idx
= (int)(((int64_t)cv
* ct
- (int64_t)sv
* st
+ 0x20000000) >> 30);
276 sv
= (int)(((int64_t)cv
* st
+ (int64_t)sv
* ct
+ 0x20000000) >> 30);
281 ct
= (int)(((int64_t)av_costbl_4_sf
[idx
& 0x1f] * (0x800 - (a
& 0x7ff)) +
282 (int64_t)av_costbl_4_sf
[(idx
& 0x1f)+1]*(a
& 0x7ff) +
284 st
= (int)(((int64_t)av_sintbl_4_sf
[idx
& 0x1f] * (0x800 - (a
& 0x7ff)) +
285 (int64_t)av_sintbl_4_sf
[(idx
& 0x1f) + 1] * (a
& 0x7ff) +
288 *c
= (int)(((int64_t)cv
* ct
- (int64_t)sv
* st
+ 0x20000000) >> 30);
290 *s
= (int)(((int64_t)cv
* st
+ (int64_t)sv
* ct
+ 0x20000000) >> 30);
293 #endif /* AVUTIL_SOFTFLOAT_H */