PandA-2024.02
fixedptc.c
Go to the documentation of this file.
1 #include <stdio.h>
2 #include <string.h>
3 #include <unistd.h>
4 #include <stdint.h>
5 #include <assert.h>
6 #include "fixedptc.h"
7 
8 
9 static char str[25];
10 /* Multiplies two fixedpt numbers, returns the result. */
11 fixedpt
13 {
14  fixedpt ret = (((fixedptd)A * (fixedptd)B) >> FIXEDPT_FBITS);
15  if (A > 0 && B > 0 && ret < 0)
16  assert("MUL: sign change\n");
17  if (A < 0 && B < 0 && ret > 0)
18  assert("MUL: sign change\n");
19  return ret;
20 }
21 
22 
23 /* Divides two fixedpt numbers, returns the result. */
24 fixedpt
26 {
27  fixedpt ret = (((fixedptd)A << FIXEDPT_FBITS) / (fixedptd)B);
28  if (A > 0 && B > 0 && ret < 0)
29  assert("DIV: sign change\n");
30  if (A < 0 && B < 0 && ret > 0)
31  assert("DIV: sign change\n");
32  return ret;
33 }
34 
35 /*
36  * Note: adding and substracting fixedpt numbers can be done by using
37  * the regular integer operators + and -.
38  */
39 
49 void
50 fixedpt_str(fixedpt A, char *str, int max_dec)
51 {
52  int ndec = 0, slen = 0;
53  char tmp[12] = {0};
54  fixedptud fr, ip;
55  const fixedptud one = (fixedptud)1 << FIXEDPT_BITS;
56  const fixedptud mask = one - 1;
57 
58  if (max_dec == -1)
59 #if FIXEDPT_BITS == 32
60  max_dec = 2;
61 #elif FIXEDPT_BITS == 64
62  max_dec = 10;
63 #else
64 #error Invalid width
65 #endif
66  else if (max_dec == -2)
67  max_dec = 15;
68 
69  if (A < 0) {
70  str[slen++] = '-';
71  A *= -1;
72  }
73 
74  ip = fixedpt_toint(A);
75  do {
76  tmp[ndec++] = '0' + ip % 10;
77  ip /= 10;
78  } while (ip != 0);
79 
80  while (ndec > 0)
81  str[slen++] = tmp[--ndec];
82  str[slen++] = '.';
83 
84  // printf("before shift left %x\n", fr);
85  fr = (fixedpt_fracpart(A) << FIXEDPT_WBITS) & mask;
86 // printf("before iter %x\n", fr);
87  do {
88  fr = (fr & mask) * 10;
89  // printf("iter %x\n", fr);
90  str[slen++] = '0' + (fr >> FIXEDPT_BITS) % 10;
91  // printf("char %c\n", '0' + (fr >> FIXEDPT_BITS) % 10);
92  ndec++;
93  } while (fr != 0 && ndec < max_dec);
94 
95  if (ndec > 1 && str[slen-1] == '0')
96  str[slen-1] = '\0'; /* cut off trailing 0 */
97  else
98  str[slen] = '\0';
99 }
100 
101 /* Converts the given fixedpt number into a string, using a static
102  * (non-threadsafe) string buffer */
103 char*
104 fixedpt_cstr(const fixedpt A, const int max_dec)
105 {
106 
107  fixedpt_str(A, str, max_dec);
108  return (str);
109 }
110 
111 
112 /* Returns the square root of the given number, or -1 in case of error */
113 fixedpt
115 {
116  int invert = 0;
117  int iter = FIXEDPT_FBITS;
118  // int l, i;
119  int i;
120  fixedpt l;
121 
122  if (A < 0)
123  return (-1);
124  if (A == 0 || A == FIXEDPT_ONE)
125  return (A);
126  if (A < FIXEDPT_ONE && A > 6) {
127  invert = 1;
128  A = fixedpt_div(FIXEDPT_ONE, A);
129  }
130  if (A > FIXEDPT_ONE) {
131  fixedpt s = A; //??? janders int s = A;
132 
133  iter = 0;
134  while (s > 0) {
135  s >>= 2;
136  iter++;
137  }
138  }
139 
140  /* Newton's iterations */
141  l = (A >> 1) + 1;
142  for (i = 0; i < iter; i++)
143  l = (l + fixedpt_div(A, l)) >> 1;
144  if (invert)
145  return (fixedpt_div(FIXEDPT_ONE, l));
146  return (l);
147 }
148 
149 
150 /* Returns the sine of the given fixedpt number.
151  * Note: the loss of precision is extraordinary! */
152 fixedpt
154 {
155  int sign = 1;
156  fixedpt sqr, result;
157  const fixedpt SK[2] = {
158  fixedpt_rconst(7.61e-03),
159  fixedpt_rconst(1.6605e-01)
160  };
161 
162  fp %= 2 * FIXEDPT_PI;
163  if (fp < 0)
164  fp = FIXEDPT_PI * 2 + fp;
165  if ((fp > FIXEDPT_HALF_PI) && (fp <= FIXEDPT_PI))
166  fp = FIXEDPT_PI - fp;
167  else if ((fp > FIXEDPT_PI) && (fp <= (FIXEDPT_PI + FIXEDPT_HALF_PI))) {
168  fp = fp - FIXEDPT_PI;
169  sign = -1;
170  } else if (fp > (FIXEDPT_PI + FIXEDPT_HALF_PI)) {
171  fp = (FIXEDPT_PI << 1) - fp;
172  sign = -1;
173  }
174  sqr = fixedpt_mul(fp, fp);
175  result = SK[0];
176  result = fixedpt_mul(result, sqr);
177  result -= SK[1];
178  result = fixedpt_mul(result, sqr);
179  result += FIXEDPT_ONE;
180  result = fixedpt_mul(result, fp);
181  return sign * result;
182 }
183 
184 
185 /* Returns the cosine of the given fixedpt number */
186 fixedpt
188 {
189  return (fixedpt_sin(FIXEDPT_HALF_PI - A));
190 }
191 
192 
193 /* Returns the tangens of the given fixedpt number */
194 fixedpt
196 {
197  return fixedpt_div(fixedpt_sin(A), fixedpt_cos(A));
198 }
199 
200 
201 /* Returns the value exp(x), i.e. e^x of the given fixedpt number. */
202 fixedpt
204 {
205  fixedpt xabs, k, z, R, xp, ans;
206  const fixedpt LN2 = fixedpt_rconst(0.69314718055994530942);
207  const fixedpt LN2_INV = fixedpt_rconst(1.4426950408889634074);
208  const fixedpt EXP_P[5] = {
209  fixedpt_rconst(1.66666666666666019037e-01),
210  fixedpt_rconst(-2.77777777770155933842e-03),
211  fixedpt_rconst(6.61375632143793436117e-05),
212  fixedpt_rconst(-1.65339022054652515390e-06),
213  fixedpt_rconst(4.13813679705723846039e-08),
214  };
215 
216  if (fp == 0){
217 // printf("excuted fp = 0 ");
218  return (FIXEDPT_ONE);
219  }
220 
221 
222  xabs = fixedpt_abs(fp);
223 // printf("xabs = fixedpt_abs(fp); = ");
224 // fixedpt_print(xabs);
225 
226  k = fixedpt_mul(xabs, LN2_INV);
227  //switch the exponents to base 2
228  //now calculating 2^k
229 // printf("k = fixedpt_mul(xabs, LN2_INV); = ");
230 // fixedpt_print(k);
231 
232  k += FIXEDPT_ONE_HALF;
233 // printf("k += FIXEDPT_ONE_HALF; = ");
234 // fixedpt_print(k);
235 
236  k &= ~FIXEDPT_FMASK;
237 // printf("k &= ~FIXEDPT_FMASK; = ");
238 // fixedpt_print(k);
239 
240  if (fp < 0){
241  k = -k;
242 // printf("k = -k; = ");
243 // fixedpt_print(k);
244  }
245 
246  fp -= fixedpt_mul(k, LN2);
247 // printf("fp -= fixedpt_mul(k, LN2);");
248 // fixedpt_print(fp);
249 
250  z = fixedpt_mul(fp, fp);
251 // printf("z = fixedpt_mul(fp, fp); = ");
252 // fixedpt_print(z);
253 
254 
255  /* Taylor */
256  R = FIXEDPT_TWO +
257  fixedpt_mul(z, EXP_P[0] + fixedpt_mul(z, EXP_P[1] +
258  fixedpt_mul(z, EXP_P[2] + fixedpt_mul(z, EXP_P[3] +
259  fixedpt_mul(z, EXP_P[4])))));
260 // printf("R = FIXEDPT_TWO +"
261 // "fixedpt_mul(z, EXP_P[0] + fixedpt_mul(z, EXP_P[1] +"
262 // "fixedpt_mul(z, EXP_P[2] + fixedpt_mul(z, EXP_P[3] +"
263 // "fixedpt_mul(z, EXP_P[4])))));= ");
264 // fixedpt_print(R);
265 
266 
267  xp = FIXEDPT_ONE + fixedpt_div(fixedpt_mul(fp, FIXEDPT_TWO), R - fp);
268 // printf("xp = FIXEDPT_ONE + fixedpt_div(fixedpt_mul(fp, FIXEDPT_TWO), R - fp); ");
269 // fixedpt_print(xp);
270 
271 
272  if (k < 0){
273  k = FIXEDPT_ONE >> (-k >> FIXEDPT_FBITS);
274 // printf("k = FIXEDPT_ONE >> (-k >> FIXEDPT_FBITS);");
275 // fixedpt_print(k);
276  }
277  else{
278  k = FIXEDPT_ONE << (k >> FIXEDPT_FBITS);
279 // printf("k = FIXEDPT_ONE << (k >> FIXEDPT_FBITS);");
280 // fixedpt_print(k);
281  }
282  ans = fixedpt_mul(k, xp);
283 // printf("ans = fixedpt_mul(k, xp)");
284 // fixedpt_print(ans);
285  return (ans);
286 }
287 
288 
289 /* Returns the natural logarithm of the given fixedpt number. */
290 fixedpt
292 {
293  const fixedpt table[] = {-363409, -317983, -291410, -272557, -257933, -245984, -235882, -227130, -219411, -212507, -206260, -200558, -195312, -190455, -185934, -181704, -177731, -173985, -170442, -167080, -163883, -160834, -157921, -155132, -152457, -149886, -147413, -145029, -142730, -140508, -138359, -136278, -134262, -132305, -130405, -128559, -126764, -125016, -123314, -121654, -120036, -118457, -116915, -115408, -113935, -112495, -111085, -109706, -108354, -107030, -105733, -104460, -103212, -101987, -100784, -99603, -98443, -97304, -96183, -95082, -93999, -92933, -91884, -90852, -89836, -88836, -87850, -86879, -85922, -84979, -84050, -83133, -82229, -81338, -80458, -79590, -78733, -77887, -77053, -76228, -75414, -74610, -73816, -73031, -72255, -71489, -70731, -69982, -69241, -68509, -67785, -67069, -66360, -65659, -64966, -64280, -63600, -62928, -62263, -61604, -60952, -60307, -59667, -59034, -58407, -57786, -57170, -56561, -55957, -55358, -54765, -54177, -53595, -53017, -52445, -51877, -51315, -50757, -50204, -49656, -49112, -48572, -48037, -47507, -46980, -46458, -45940, -45426, -44916, -44410, -43908, -43409, -42915, -42424, -41937, -41453, -40973, -40496, -40023, -39553, -39087, -38624, -38164, -37707, -37254, -36803, -36356, -35911, -35470, -35032, -34596, -34164, -33734, -33307, -32883, -32461, -32043, -31627, -31213, -30802, -30394, -29988, -29585, -29184, -28786, -28390, -27996, -27605, -27216, -26829, -26445, -26063, -25683, -25305, -24929, -24556, -24185, -23815, -23448, -23083, -22720, -22359, -22000, -21643, -21288, -20934, -20583, -20233, -19886, -19540, -19196, -18854, -18513, -18174, -17837, -17502, -17169, -16837, -16507, -16178, -15851, -15526, -15202, -14880, -14560, -14241, -13924, -13608, -13294, -12981, -12669, -12360, -12051, -11744, -11439, -11135, -10832, -10530, -10231, -9932, -9635, -9339, -9044, -8751, -8459, -8169, -7879, -7591, -7304, -7019, -6734, -6451, -6169, -5889, -5609, -5331, -5054, -4778, -4503, -4230, -3957, -3686, -3415, -3146, -2878, -2611, -2345, -2081, -1817, -1554, -1293, -1032, -773, -514, -257, 0};
294  return table[(x >> (FIXEDPT_FBITS-8)) & 0xFF];
295 #if 0 // janders
296  fixedpt log2, xi;
297  fixedpt f, s, z, w, R;
298  const fixedpt LN2 = fixedpt_rconst(0.69314718055994530942);
299  const fixedpt LG[7] = {
300  fixedpt_rconst(6.666666666666735130e-01),
301  fixedpt_rconst(3.999999999940941908e-01),
302  fixedpt_rconst(2.857142874366239149e-01),
303  fixedpt_rconst(2.222219843214978396e-01),
304  fixedpt_rconst(1.818357216161805012e-01),
305  fixedpt_rconst(1.531383769920937332e-01),
306  fixedpt_rconst(1.479819860511658591e-01)
307  };
308 
309  if (x < 0)
310  return (0);
311  if (x == 0)
312  return 0xffffffff;
313 
314  log2 = 0;
315  xi = x;
316  while (xi > FIXEDPT_TWO) {
317  xi >>= 1;
318  log2++;
319  }
320  f = xi - FIXEDPT_ONE;
321  s = fixedpt_div(f, FIXEDPT_TWO + f);
322  z = fixedpt_mul(s, s);
323  w = fixedpt_mul(z, z);
324  R = fixedpt_mul(w, LG[1] + fixedpt_mul(w, LG[3]
325  + fixedpt_mul(w, LG[5]))) + fixedpt_mul(z, LG[0]
326  + fixedpt_mul(w, LG[2] + fixedpt_mul(w, LG[4]
327  + fixedpt_mul(w, LG[6]))));
328  return (fixedpt_mul(LN2, (log2 << FIXEDPT_FBITS)) + f
329  - fixedpt_mul(s, f - R));
330 #endif
331 }
332 
333 
334 /* Returns the logarithm of the given base of the given fixedpt number */
335 fixedpt
337 {
338  return (fixedpt_div(fixedpt_ln(x), fixedpt_ln(base)));
339 }
340 
341 
342 /* Return the power value (n^exp) of the given fixedpt numbers */
343 fixedpt
345 {
346  if (exp == 0)
347  return (FIXEDPT_ONE);
348  if (n < 0)
349  return 0;
350  return (fixedpt_exp(fixedpt_mul(fixedpt_ln(n), exp)));
351 }
352 /*
353 void
354 fixedpt_print(fixedpt A)
355 {
356  char num[30];
357 
358  fixedpt_str(A, num, -2);
359  puts(num);
360 }
361 */
362 /*
363 void
364 fixedpt_print_file(fixedpt A)
365 {
366  char num[30];
367  int j;
368  FILE *output;
369  output = fopen ( "MonteCarlo.txt", "a" );
370 
371  if ( !output )
372  {
373  fprintf ( stderr, "\n" );
374  fprintf ( stderr, "fixedpt_print_file - Fatal error!\n" );
375  fprintf ( stderr, " Could not open the output file.\n" );
376  return;
377  }
378  //c printf("PRINT_FUNCTON **********************************************\n");
379 // for ( j = 0; j <= n; j++ )
380 // {
381  fixedpt_str(A, num, -2);
382  printf("Blahhhh");
383  puts(num);
384  fputs(num, output);
385  fprintf(output, "\n");
386  //fprintf ( output, " %24.16g\n", num );
387  // }
388 }*/
389 
fixedpt fixedpt_sqrt(fixedpt A)
Definition: fixedptc.c:96
#define FIXEDPT_FBITS
Definition: fixedptc.h:104
char base
This version is stamped on May 10, 2016.
Definition: nussinov.c:24
void fixedpt_str(fixedpt A, char *str, int max_dec)
Convert the given fixedpt number to a decimal string.
Definition: fixedptc.c:35
#define R
Definition: mips.c:40
fixedpt fixedpt_log(fixedpt x, fixedpt base)
Definition: fixedptc.c:298
#define FIXEDPT_ONE_HALF
Definition: fixedptc.h:119
fixedpt fixedpt_pow(fixedpt n, fixedpt exp)
Definition: fixedptc.c:304
#define FIXEDPT_BITS
Definition: fixedptc.h:75
fixedpt fixedpt_ln(fixedpt x)
Definition: fixedptc.c:259
#define fixedpt_toint(F)
Definition: fixedptc.h:109
#define A
Definition: generate.c:13
#define FIXEDPT_TWO
Definition: fixedptc.h:120
#define FIXEDPT_PI
Definition: fixedptc.h:121
#define FIXEDPT_FMASK
Definition: fixedptc.h:105
static const uint32_t k[]
Definition: sha-256.c:22
fixedpt fixedpt_tan(fixedpt A)
Definition: fixedptc.c:168
fixedpt fixedpt_exp(fixedpt fp)
Definition: fixedptc.c:174
#define fixedpt_fracpart(A)
Definition: fixedptc.h:116
fixedpt fixedpt_mul(fixedpt A, fixedpt B)
Definition: fixedptc.c:11
fixedpt fixedpt_sin(fixedpt fp)
Definition: fixedptc.c:130
fixedpt fixedpt_div(fixedpt A, fixedpt B)
Definition: fixedptc.c:17
int result[SIZE]
Definition: adpcm.c:800
char * fixedpt_cstr(const fixedpt A, const int max_dec)
Definition: fixedptc.c:88
fixedpt fixedpt_cos(fixedpt A)
Definition: fixedptc.c:162
int64_t fixedptd
Definition: fixedptc.h:80
char str[25]
Definition: fixedptc.c:8
uint64_t fixedptud
Definition: fixedptc.h:82
#define fixedpt_rconst(R)
Definition: fixedptc.h:107
uint32_t sign
x
Return the smallest n such that 2^n >= _x.
#define FIXEDPT_ONE
Definition: fixedptc.h:118
#define fixedpt_abs(A)
Definition: fixedptc.h:126
#define B
Definition: generate.c:14
int32_t fixedpt
Definition: fixedptc.h:79
uint32_t exp
#define FIXEDPT_HALF_PI
Definition: fixedptc.h:123
#define FIXEDPT_WBITS
Definition: fixedptc.h:95

Generated on Mon Feb 12 2024 13:02:49 for PandA-2024.02 by doxygen 1.8.13