From 9477dbe667f250ecd23f8fc0d56b942191526421 Mon Sep 17 00:00:00 2001 From: Franciszek Malinka Date: Thu, 25 Feb 2021 14:42:55 +0100 Subject: Stare semestry, niepoukladane --- Semestr 3/anm/cordic/cordic.cpp | 189 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 189 insertions(+) create mode 100644 Semestr 3/anm/cordic/cordic.cpp (limited to 'Semestr 3/anm/cordic/cordic.cpp') diff --git a/Semestr 3/anm/cordic/cordic.cpp b/Semestr 3/anm/cordic/cordic.cpp new file mode 100644 index 0000000..b0dfd39 --- /dev/null +++ b/Semestr 3/anm/cordic/cordic.cpp @@ -0,0 +1,189 @@ +#include +#include +//#define M_PI 3.1415926536897932384626 +int main(int argc, char **argv) +{ + FILE *f; + char tname[50], cname[10]; + int n, n2, mp2, niter, bits, t; + double F, A, mul, tmul; // CORDIC gain, convergence angle, multiplication factor + printf("0)circular, 1)linear, 2)hyperbolic? "); + scanf("%d", &t); + switch (t) + { + case 0: + sprintf(cname, "%s", ""); + break; + case 1: + sprintf(cname, "%s", "_LIN"); + break; + case 2: + sprintf(cname, "%s", "_HYPER"); + break; + } + sprintf(tname, "CORDICtable%s.c", cname); + if (NULL == (f = fopen(tname, "wt"))) + { + printf("cannot write to %s\n", tname); + return 0; + } + + printf("number of bits for mantissa (e.g. 30)? "); + scanf("%d", &bits); + printf("0) mul factor is 2^n (easier output scaling), or\n" + "1) 2pi is 2^n (easier implementation)\n ? "); + scanf("%d", &mp2); + printf("suggested multiplication factor "); + if (mp2 == 0) + { + tmul = (double)(1 << (bits - 3)); + printf("2^%d = %f\n", bits - 3, tmul); + } + else + { + tmul = (double)(1 << (bits - 2)) / M_PI; + printf("2^%d/pi = %f\n", bits - 2, tmul); + } + printf("multiplication factor (0 for suggested)? "); + scanf("%lf", &mul); + if (mul < 0.1) + { + mul = tmul; + printf("%f\n", mul); + } + else + mp2 = -1; // custom mul factor + switch (t) + { + case 0: + for (n = 0; n < bits; n++) + if ((int)round(atan(pow(2.0, (double)(-n))) * mul) == 0) + break; + break; + case 1: + for (n = 0; n < bits; n++) + if ((int)round((pow(2.0, (double)(-n))) * mul) == 0) + break; + break; + case 2: + for (n = 1, n2 = 4; n < bits;) + { + if ((int)round(atanh(pow(2.0, (double)(-n))) * mul) == 0) + break; + if (n == n2) + n2 = 3 * n + 1; + else + n++; + } + break; + } + printf("iterations (up to %d)? ", n); + scanf("%d", &niter); + + F = 1.0; + A = 0.0; + switch (t) + { + case 0: + for (n = 0; n < niter; n++) + { + F = F * sqrt(1 + pow(2.0, -2.0 * n)); + A += atan(pow(2.0, (double)(-n))); + } + break; + case 1: + for (n = 0; n < niter; n++) + { + F = F * sqrt(1); + A += (pow(2.0, (double)(-n))); + } + break; + case 2: + for (n = 1, n2 = 4; n < niter;) + { + F = F * sqrt(1 - pow(2.0, -2.0 * n)); + A += atanh(pow(2.0, (double)(-n))); + if (n == n2) + n2 = 3 * n + 1; + else + n++; + } + break; + } + + fprintf(f, "//CORDIC%s, %d bits, %d iterations\n", cname, bits, niter); + fprintf(f, "// 1.0 = %f multiplication factor\n", mul); + switch (t) + { + case 0: + fprintf(f, "// A = %lf convergence angle " + "(limit is 1.7432866 = 99.9deg)\n", + A); + fprintf(f, "// F = %lf gain (limit is 1.64676025812107)\n", F); + fprintf(f, "// 1/F = %lf inverse gain (limit is 0.607252935008881)\n", 1.0 / F); + break; + case 1: + fprintf(f, "// A = %lf convergence angle (limit is 2)\n", A); + fprintf(f, "// F = %lf gain (limit is 1.0)\n", F); + fprintf(f, "// 1/F = %lf inverse gain (limit is 1.0)\n", 1.0 / F); + break; + case 2: + fprintf(f, "// A = %lf convergence angle " + "(limit is 1.1181730 = 64.0deg)\n", + A); + fprintf(f, "// F = %lf gain (limit is 0.82978162013890)\n", F); + fprintf(f, "// 1/F = %lf inverse gain (limit is 1.20513635844646)\n", 1.0 / F); + break; + } + fprintf(f, "// pi = %lf (3.1415926536897932384626)\n", M_PI); + fprintf(f, "\n"); + fprintf(f, "#define CORDIC%s_A %f // CORDIC convergence angle A\n", cname, A); + fprintf(f, "#define CORDIC%s_F 0x%08X // CORDIC gain F\n", + cname, (int)round(mul * F)); + fprintf(f, "#define CORDIC%s_1F 0x%08X // CORDIC inverse gain 1/F\n", + cname, (int)round(mul / F)); + fprintf(f, "#define CORDIC%s_HALFPI 0x%08X\n", cname, (int)round(mul * (M_PI / 2.0))); + fprintf(f, "#define CORDIC%s_PI 0x%08X\n", cname, (int)round(mul * (M_PI))); + fprintf(f, "#define CORDIC%s_TWOPI 0x%08X\n", cname, (int)round(mul * (2.0 * M_PI))); + fprintf(f, "#define CORDIC%s_MUL %f // CORDIC multiplication factor M", cname, mul); + switch (mp2) + { + case 0: + fprintf(f, " = 2^%d\n", bits - 3); + break; + case 1: + fprintf(f, " = 2^%d/pi\n", bits - 2); + break; + default: + fprintf(f, "\n"); + break; + } + fprintf(f, "#define CORDIC%s_MAXITER %d\n\n", cname, niter); + fprintf(f, "int CORDIC%s_ZTBL[] = {", cname); + for (n = 0; n < niter; n++) + { + if ((n % 8) == 0) + fprintf(f, "\n "); + switch (t) + { + case 0: + fprintf(f, "0x%08X", (int)round(atan(pow(2.0, (double)(-n))) * mul)); + break; + case 1: + fprintf(f, "0x%08X", (int)round((pow(2.0, (double)(-n))) * mul)); + break; + case 2: + n = n == 0 ? 1 : n; + fprintf(f, "0x%08X", (int)round(atanh(pow(2.0, (double)(-n))) * mul)); + break; + } + if (n < (niter - 1)) + fprintf(f, ", "); + else + fprintf(f, " "); + } + fprintf(f, "};\n\n"); + fclose(f); + printf("table written to %s\n", tname); + return 0; +} -- cgit v1.2.3