FFmpeg
softfloat.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
3  *
4  * This file is part of FFmpeg.
5  *
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.
10  *
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.
15  *
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
19  */
20 
21 #ifndef AVUTIL_SOFTFLOAT_H
22 #define AVUTIL_SOFTFLOAT_H
23 
24 #include <stdint.h>
25 #include "common.h"
26 
27 #include "avassert.h"
28 #include "softfloat_tables.h"
29 
30 #define MIN_EXP -149
31 #define MAX_EXP 126
32 #define ONE_BITS 29
33 
34 typedef struct SoftFloat{
37 }SoftFloat;
38 
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};
47 
48 
49 /**
50  * Convert a SoftFloat to a double precision float.
51  */
52 static inline av_const double av_sf2double(SoftFloat v) {
53  v.exp -= ONE_BITS +1;
54  return ldexp(v.mant, v.exp);
55 }
56 
58  if(a.mant){
59 #if 1
60  while((a.mant + 0x1FFFFFFFU)<0x3FFFFFFFU){
61  a.mant += a.mant;
62  a.exp -= 1;
63  }
64 #else
65  int s=ONE_BITS - av_log2(FFABS(a.mant));
66  a.exp -= s;
67  a.mant <<= s;
68 #endif
69  if(a.exp < MIN_EXP){
70  a.exp = MIN_EXP;
71  a.mant= 0;
72  }
73  }else{
74  a.exp= MIN_EXP;
75  }
76  return a;
77 }
78 
80 #if 1
81  if((int32_t)(a.mant + 0x40000000U) <= 0){
82  a.exp++;
83  a.mant>>=1;
84  }
85  av_assert2(a.mant < 0x40000000 && a.mant > -0x40000000);
86  av_assert2(a.exp <= MAX_EXP);
87  return a;
88 #elif 1
89  int t= a.mant + 0x40000000 < 0;
90  return (SoftFloat){ a.mant>>t, a.exp+t};
91 #else
92  int t= (a.mant + 0x3FFFFFFFU)>>31;
93  return (SoftFloat){a.mant>>t, a.exp+t};
94 #endif
95 }
96 
97 /**
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.
101  */
103  a.exp += b.exp;
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)
108  return FLOAT_0;
109  return a;
110 }
111 
112 /**
113  * b has to be normalized and not zero.
114  * @return Will not be more denormalized than a.
115  */
117  int64_t temp = (int64_t)a.mant * (1<<(ONE_BITS+1));
118  temp /= b.mant;
119  a.exp -= b.exp;
120  a.mant = temp;
121  while (a.mant != temp) {
122  temp /= 2;
123  a.exp--;
124  a.mant = temp;
125  }
126  a = av_normalize1_sf(a);
127  if (!a.mant || a.exp < MIN_EXP)
128  return FLOAT_0;
129  return a;
130 }
131 
132 /**
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
137  */
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);
143  else return a.mant ;
144 }
145 
146 /**
147  * Compares two SoftFloats.
148  * @returns 1 if a is greater than b, 0 otherwise
149  */
150 static inline av_const int av_gt_sf(SoftFloat a, SoftFloat b)
151 {
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 ;
157 }
158 
159 /**
160  * @returns the sum of 2 SoftFloats.
161  */
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}));
167  else return a;
168 }
169 
170 /**
171  * @returns the difference of 2 SoftFloats.
172  */
174  return av_add_sf(a, (SoftFloat){ -b.mant, b.exp});
175 }
176 
177 //FIXME log, exp, pow
178 
179 /**
180  * Converts a mantisse and exponent to a SoftFloat.
181  * This converts a fixed point value v with frac_bits fractional bits to a
182  * SoftFloat.
183  * @returns a SoftFloat with value v * 2^-frac_bits
184  */
185 static inline av_const SoftFloat av_int2sf(int v, int frac_bits){
186  int exp_offset = 0;
187  if(v <= INT_MIN + 1){
188  exp_offset = 1;
189  v>>=1;
190  }
191  return av_normalize_sf(av_normalize1_sf((SoftFloat){v, ONE_BITS + 1 - frac_bits + exp_offset}));
192 }
193 
194 /**
195  * Converts a SoftFloat to an integer.
196  * Rounding is to -inf.
197  */
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);
202 }
203 
204 /**
205  * Rounding-to-nearest used.
206  */
208 {
209  int tabIndex, rem;
210 
211  if (val.mant == 0)
212  val.exp = MIN_EXP;
213  else if (val.mant < 0)
214  abort();
215  else
216  {
217  tabIndex = (val.mant - 0x20000000) >> 20;
218 
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 +
222  0x80000) >> 20);
223  val.mant = (int)(((int64_t)av_sqr_exp_multbl_sf[val.exp & 1] * val.mant +
224  0x10000000) >> 29);
225 
226  if (val.mant < 0x40000000)
227  val.exp -= 2;
228  else
229  val.mant >>= 1;
230 
231  val.exp = (val.exp >> 1) + 1;
232  }
233 
234  return val;
235 }
236 
237 /**
238  * Rounding-to-nearest used.
239  */
240 static av_unused void av_sincos_sf(int a, int *s, int *c)
241 {
242  int idx, sign;
243  int sv, cv;
244  int st, ct;
245 
246  idx = a >> 26;
247  sign = (int32_t)((unsigned)idx << 27) >> 31;
248  cv = av_costbl_1_sf[idx & 0xf];
249  cv = (cv ^ sign) - sign;
250 
251  idx -= 8;
252  sign = (int32_t)((unsigned)idx << 27) >> 31;
253  sv = av_costbl_1_sf[idx & 0xf];
254  sv = (sv ^ sign) - sign;
255 
256  idx = a >> 21;
257  ct = av_costbl_2_sf[idx & 0x1f];
258  st = av_sintbl_2_sf[idx & 0x1f];
259 
260  idx = (int)(((int64_t)cv * ct - (int64_t)sv * st + 0x20000000) >> 30);
261 
262  sv = (int)(((int64_t)cv * st + (int64_t)sv * ct + 0x20000000) >> 30);
263 
264  cv = idx;
265 
266  idx = a >> 16;
267  ct = av_costbl_3_sf[idx & 0x1f];
268  st = av_sintbl_3_sf[idx & 0x1f];
269 
270  idx = (int)(((int64_t)cv * ct - (int64_t)sv * st + 0x20000000) >> 30);
271 
272  sv = (int)(((int64_t)cv * st + (int64_t)sv * ct + 0x20000000) >> 30);
273  cv = idx;
274 
275  idx = a >> 11;
276 
277  ct = (int)(((int64_t)av_costbl_4_sf[idx & 0x1f] * (0x800 - (a & 0x7ff)) +
278  (int64_t)av_costbl_4_sf[(idx & 0x1f)+1]*(a & 0x7ff) +
279  0x400) >> 11);
280  st = (int)(((int64_t)av_sintbl_4_sf[idx & 0x1f] * (0x800 - (a & 0x7ff)) +
281  (int64_t)av_sintbl_4_sf[(idx & 0x1f) + 1] * (a & 0x7ff) +
282  0x400) >> 11);
283 
284  *c = (int)(((int64_t)cv * ct + (int64_t)sv * st + 0x20000000) >> 30);
285 
286  *s = (int)(((int64_t)cv * st + (int64_t)sv * ct + 0x20000000) >> 30);
287 }
288 
289 #endif /* AVUTIL_SOFTFLOAT_H */
softfloat_tables.h
FLOAT_EPSILON
static const SoftFloat FLOAT_EPSILON
A small value.
Definition: softfloat.h:42
MAX_EXP
#define MAX_EXP
Definition: softfloat.h:31
av_sqr_exp_multbl_sf
static const int32_t av_sqr_exp_multbl_sf[2]
Definition: softfloat_tables.h:184
FLOAT_05
static const SoftFloat FLOAT_05
0.5
Definition: softfloat.h:40
av_unused
#define av_unused
Definition: attributes.h:131
av_sub_sf
static av_const SoftFloat av_sub_sf(SoftFloat a, SoftFloat b)
Definition: softfloat.h:173
av_const
#define av_const
Definition: attributes.h:84
b
#define b
Definition: input.c:40
SoftFloat::mant
int32_t mant
Definition: softfloat.h:35
av_sintbl_3_sf
static const int32_t av_sintbl_3_sf[32]
Definition: softfloat_tables.h:228
MIN_EXP
#define MIN_EXP
Definition: softfloat.h:30
FLOAT_1
static const SoftFloat FLOAT_1
1.0
Definition: softfloat.h:41
av_gt_sf
static av_const int av_gt_sf(SoftFloat a, SoftFloat b)
Compares two SoftFloats.
Definition: softfloat.h:150
av_sf2int
static av_const int av_sf2int(SoftFloat v, int frac_bits)
Converts a SoftFloat to an integer.
Definition: softfloat.h:198
U
#define U(x)
Definition: vp56_arith.h:37
av_sqrt_sf
static av_always_inline SoftFloat av_sqrt_sf(SoftFloat val)
Rounding-to-nearest used.
Definition: softfloat.h:207
av_div_sf
static av_const SoftFloat av_div_sf(SoftFloat a, SoftFloat b)
b has to be normalized and not zero.
Definition: softfloat.h:116
val
static double val(void *priv, double ch)
Definition: aeval.c:76
avassert.h
FLOAT_MIN
static const SoftFloat FLOAT_MIN
Definition: softfloat.h:46
s
#define s(width, name)
Definition: cbs_vp9.c:257
av_sf2double
static av_const double av_sf2double(SoftFloat v)
Convert a SoftFloat to a double precision float.
Definition: softfloat.h:52
av_costbl_3_sf
static const int32_t av_costbl_3_sf[32]
Definition: softfloat_tables.h:217
FFABS
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition: common.h:65
FLOAT_0
static const SoftFloat FLOAT_0
0.0
Definition: softfloat.h:39
SoftFloat::exp
int32_t exp
Definition: softfloat.h:36
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
av_sintbl_4_sf
static const int32_t av_sintbl_4_sf[33]
Definition: softfloat_tables.h:251
av_costbl_1_sf
static const int32_t av_costbl_1_sf[16]
Definition: softfloat_tables.h:188
FLOAT_0999999
static const SoftFloat FLOAT_0999999
0.999999
Definition: softfloat.h:45
av_sintbl_2_sf
static const int32_t av_sintbl_2_sf[32]
Definition: softfloat_tables.h:206
av_cmp_sf
static av_const int av_cmp_sf(SoftFloat a, SoftFloat b)
Compares two SoftFloats.
Definition: softfloat.h:138
FLOAT_1584893192
static const SoftFloat FLOAT_1584893192
1.584893192 (10^.2)
Definition: softfloat.h:43
FLOAT_100000
static const SoftFloat FLOAT_100000
100000
Definition: softfloat.h:44
ONE_BITS
#define ONE_BITS
Definition: softfloat.h:32
av_normalize_sf
static av_const SoftFloat av_normalize_sf(SoftFloat a)
Definition: softfloat.h:57
a
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:41
av_assert2
#define av_assert2(cond)
assert() equivalent, that does lie in speed critical code.
Definition: avassert.h:64
SoftFloat
Definition: softfloat.h:34
common.h
av_always_inline
#define av_always_inline
Definition: attributes.h:49
av_int2sf
static av_const SoftFloat av_int2sf(int v, int frac_bits)
Converts a mantisse and exponent to a SoftFloat.
Definition: softfloat.h:185
av_sqrttbl_sf
static const int32_t av_sqrttbl_sf[512+1]
Definition: softfloat_tables.h:52
av_sincos_sf
static av_unused void av_sincos_sf(int a, int *s, int *c)
Rounding-to-nearest used.
Definition: softfloat.h:240
av_add_sf
static av_const SoftFloat av_add_sf(SoftFloat a, SoftFloat b)
Definition: softfloat.h:162
temp
else temp
Definition: vf_mcdeint.c:248
av_normalize1_sf
static av_const SoftFloat av_normalize1_sf(SoftFloat a)
Definition: softfloat.h:79
av_costbl_2_sf
static const int32_t av_costbl_2_sf[32]
Definition: softfloat_tables.h:195
int32_t
int32_t
Definition: audioconvert.c:56
av_costbl_4_sf
static const int32_t av_costbl_4_sf[33]
Definition: softfloat_tables.h:239
int
int
Definition: ffmpeg_filter.c:153
av_log2
int av_log2(unsigned v)
Definition: intmath.c:26
av_mul_sf
static av_const SoftFloat av_mul_sf(SoftFloat a, SoftFloat b)
Definition: softfloat.h:102