Obsah
1. Matematické funkce, jejichž hodnoty lze spočítat metodou CORDIC
2. Výpočet tangenty pomocí algoritmu CORDIC
3. První demonstrační příklad – výpočet tangenty
4. Výpočet arkustangenty pomocí algoritmu CORDIC
5. Druhý demonstrační příklad – výpočet arkustangenty
6. Výpočet délky vektoru pomocí algoritmu CORDIC
7. Třetí demonstrační příklad – výpočet délky vektoru
8. Převod z kartézských do polárních souřadnic pomocí algoritmu CORDIC
9. Obsah dalšího pokračování tohoto seriálu
1. Matematické funkce, jejichž hodnoty lze spočítat metodou CORDIC
V předchozím pokračování tohoto seriálu jsme si odvodili vztahy používané iterační metodou CORDIC pro výpočet goniometrických i jiných matematických funkcí. Jednalo se o upravené rovnice určené pro rotaci vektoru okolo počátku souřadné soustavy o úhly, které jsou vybrány s ohledem na hodnotu jejich tangenty (ta musí být rovna dvojce umocněné na záporný celočíselný exponent). Po několika krocích úprav jsme došli ke vztahům:
xr=Ki (x0 – y0 di 2-i)
yr=Ki (y0 + x0 di 2-i)
kde:
Ki=cos (arctan 2-i)=1/(1+2-2i)1/2
Veškerá práce algoritmu CORDIC spočívá v tom, že se nastaví počáteční souřadnice vektoru r a iterativně se provádí rotace o předem známé úhly δ1…δn tak, aby se dosáhlo požadované hodnoty rotace δ.
Také jsme si uvedli postup uplatňovaný při výpočtu goniometrických funkcí sinus a kosinus. Na tento výpočet v dalších kapitolách navážeme a ukážeme si, jakým způsobem je možné vypočítat další goniometrické a jiné matematické funkce.
2. Výpočet tangenty pomocí algoritmu CORDIC
Výpočet goniometrické funkce tangent je odvozen z minule popsaného algoritmu pro výpočet funkcí sin() a cos(), jelikož je možné použít známý vztah:
tan α=sin α / cos α
Funkce sin() a cos() se pomocí algoritmu CORDIC počítají současně, výpočet dokonce není možné žádným způsobem rozdělit, neboť obě hodnoty jsou na sobě závislé. To znamená, že tangentu je možné vypočítat s podobnou složitostí jako tyto dvě funkce. Jediný rozdíl spočívá v tom, že není zapotřebí obě vypočtené hodnoty násobit konstantou Ki, protože se hodnota této konstanty vzájemným vydělením vypočtených hodnot vyruší. Na druhou stranu se musí aplikovat dělení, které se v některých případech (jednodušší FPU bez děličky) opět řeší iteračními metodami. Vzhledem k tomu, že se vzájemně dělí dvě obecně nepřesné hodnoty, relativní chyba výsledku roste, přesněji řečeno, je součtem relativních chyb obou mezivýsledků. Proto se při výpočtu tangenty používá větší počet iterací, než je nutné pro samostatný výpočet funkcí sin() a cos(). Praktický příklad na výpočet tangenty pomocí algoritmu CORDIC je uveden ve třetí kapitole.
3. První demonstrační příklad – výpočet tangenty
V této kapitole je uveden výpis demonstračního příkladu, který slouží pro výpočet goniometrické funkce tangent. Všimněte si, že před vlastním iteračním výpočtem je proveden test na vstup nulové hodnoty. Je to z toho důvodu, že pro nulový úhel (a také úhel blízký úhlu pravému) je relativní chyba velká a test na nulovou vstupní hodnotu je implementačně velmi jednoduchý: postačuje hradlo AND s více vstupy. Na konci iteračního výpočtu je ošetřen stav, kdy je vypočtená tangenta nekonečná, tj. jedná se buď o úhel +90° nebo –90° (π/2 resp. -π/2). V tomto případě je vrácena hodnota +∞ nebo -∞ (jedná se o makra podle normy C99).
// --------------------------------------------------------
// Výpočet hodnot funkce tan() pomocí iteračního algoritmu
// CORDIC.
// --------------------------------------------------------
#include <stdio.h>
#include <math.h>
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
// maximální počet iterací při běhu algoritmu
#define MAX_ITER 10
// "zesílení" při rotacích
#define K 0.6073
// tabulka arkustangentu úhlů
double atans[MAX_ITER];
// tabulka záporných celočíselných mocnin hodnoty 2
double pows[MAX_ITER];
// naplnění tabulek atans[] a pows[]
void createTables(void)
{
int i;
for (i=0; i<MAX_ITER; i++) {
double p=pow(2.0, -i);
atans[i]=atan(p);
pows[i]=p;
}
}
// výpočet funkce tan() pro zadaný úhel delta
double tan_cordic(double delta)
{
int i;
double x0=1.0; // nastavení počátečních podmínek
double y0=0.0;
double xn;
if (delta==0) return 0.0; // ošetření nulového úhlu
for (i=0; i<MAX_ITER; i++) { // iterační smyčka
if (delta<0) { // úhel je záporný => rotace doleva
xn=x0+y0*pows[i];
y0-=x0*pows[i];
delta+=atans[i];
}
else { // úhel je kladný => rotace doprava
xn=x0-y0*pows[i];
y0+=x0*pows[i];
delta-=atans[i];
}
x0=xn;
}
if (x0==0) // ošetření tangenty pravého úhlu
if (y0>0) return INFINITY;
else return -INFINITY;
else
return y0/x0;
}
int main(void)
{
int i;
createTables();
for (i=0; i<90; i++) { // výpočetní smyčka
double delta; // úhel, ze kterého se počítá tan
double tanval; // vypočtené hodnoty
double tanerr; // absolutní chyby
delta=i*M_PI/180.0; // převod úhlu na radiány
tanval=tan_cordic(delta); // výpočet funkce tan
tanerr=fabs(tanval-tan(delta)); // výpočet absolutních chyb
// tisk výsledků
printf("%02d\t%14.10f\t%14.10f\t%12.10f\t%8.3f%%\n",
i,
tanval,
tan(delta),
tanerr,
tanerr==0 ? 0:100.0*tanerr/tan(delta));
}
return 0;
}
// finito
Výsledky běhu prvního demonstračního příkladu jsou vypsány v následující tabulce:
úhel | tan() podle CORDIC | tan() podle FPU | absolutní chyba | relativní chyba |
---|---|---|---|---|
00 | 0,0000000000 | 0,0000000000 | 0,0000000000 | 0,00% |
01 | 0,0167816929 | 0,0174550649 | 0,0006733720 | 3,86% |
02 | 0,0363270120 | 0,0349207695 | 0,0014062425 | 4,03% |
03 | 0,0519805611 | 0,0524077793 | 0,0004272182 | 0,82% |
04 | 0,0715866282 | 0,0699268119 | 0,0016598162 | 2,37% |
05 | 0,0861978187 | 0,0874886635 | 0,0012908448 | 1,48% |
06 | 0,1059095535 | 0,1051042353 | 0,0008053183 | 0,77% |
07 | 0,1217350391 | 0,1227845609 | 0,0010495218 | 0,85% |
08 | 0,1415874009 | 0,1405408347 | 0,0010465662 | 0,74% |
09 | 0,1575619507 | 0,1583844403 | 0,0008224896 | 0,52% |
10 | 0,1776401275 | 0,1763269807 | 0,0013131468 | 0,74% |
11 | 0,1938040418 | 0,1943803091 | 0,0005762673 | 0,30% |
12 | 0,2140028799 | 0,2125565617 | 0,0014463183 | 0,68% |
13 | 0,2303992887 | 0,2308681911 | 0,0004689025 | 0,20% |
14 | 0,2510605756 | 0,2493280028 | 0,0017325728 | 0,69% |
15 | 0,2677368774 | 0,2679491924 | 0,0002123150 | 0,08% |
16 | 0,2887616814 | 0,2867453858 | 0,0020162957 | 0,70% |
17 | 0,3057652260 | 0,3057306815 | 0,0000345445 | 0,01% |
18 | 0,3229341180 | 0,3249196962 | 0,0019855782 | 0,61% |
19 | 0,3437978423 | 0,3443276133 | 0,0005297710 | 0,15% |
20 | 0,3657852506 | 0,3639702343 | 0,0018150164 | 0,50% |
21 | 0,3836037852 | 0,3838640350 | 0,0002602498 | 0,07% |
22 | 0,4061607605 | 0,4040262258 | 0,0021345346 | 0,53% |
23 | 0,4244807446 | 0,4244748162 | 0,0000059284 | 0,00% |
24 | 0,4430431000 | 0,4452286853 | 0,0021855853 | 0,49% |
25 | 0,4666146246 | 0,4663076582 | 0,0003069665 | 0,07% |
26 | 0,4856109365 | 0,4877325886 | 0,0021216521 | 0,44% |
27 | 0,5099818506 | 0,5095254495 | 0,0004564011 | 0,09% |
28 | 0,5298275522 | 0,5317094317 | 0,0018818794 | 0,35% |
29 | 0,5550831516 | 0,5543090515 | 0,0007741002 | 0,14% |
30 | 0,5757025789 | 0,5773502692 | 0,0016476903 | 0,29% |
31 | 0,6020032089 | 0,6008606190 | 0,0011425899 | 0,19% |
32 | 0,6234942951 | 0,6248693519 | 0,0013750568 | 0,22% |
33 | 0,6493847795 | 0,6494075932 | 0,0000228137 | 0,00% |
34 | 0,6718279437 | 0,6745085168 | 0,0026805731 | 0,40% |
35 | 0,7005519564 | 0,7002075382 | 0,0003444182 | 0,05% |
36 | 0,7241045321 | 0,7265425280 | 0,0024379959 | 0,34% |
37 | 0,7542797006 | 0,7535540501 | 0,0007256505 | 0,10% |
38 | 0,7790851887 | 0,7812856265 | 0,0022004378 | 0,28% |
39 | 0,8109599430 | 0,8097840332 | 0,0011759098 | 0,15% |
40 | 0,8369586757 | 0,8390996312 | 0,0021409555 | 0,26% |
41 | 0,8707272570 | 0,8692867378 | 0,0014405192 | 0,17% |
42 | 0,8985757825 | 0,9004040443 | 0,0018282618 | 0,20% |
43 | 0,9345119814 | 0,9325150861 | 0,0019968952 | 0,21% |
44 | 0,9641849623 | 0,9656887748 | 0,0015038125 | 0,16% |
45 | 0,9974099032 | 1,0000000000 | 0,0025900968 | 0,26% |
46 | 1,0371454016 | 1,0355303138 | 0,0016150878 | 0,16% |
47 | 1,0700772381 | 1,0723687100 | 0,0022914719 | 0,21% |
48 | 1,1128721912 | 1,1106125148 | 0,0022596764 | 0,20% |
49 | 1,1484652535 | 1,1503684072 | 0,0019031537 | 0,17% |
50 | 1,1948021199 | 1,1917535926 | 0,0030485273 | 0,26% |
51 | 1,2331065284 | 1,2348971565 | 0,0017906282 | 0,15% |
52 | 1,2835566823 | 1,2799416322 | 0,0036150501 | 0,28% |
53 | 1,3257681457 | 1,3270448216 | 0,0012766760 | 0,10% |
54 | 1,3810160766 | 1,3763819205 | 0,0046341561 | 0,34% |
55 | 1,4274458745 | 1,4281480067 | 0,0007021322 | 0,05% |
56 | 1,4884763418 | 1,4825609685 | 0,0059153733 | 0,40% |
57 | 1,5399190611 | 1,5398649638 | 0,0000540973 | 0,00% |
58 | 1,6038639132 | 1,6003345290 | 0,0035293841 | 0,22% |
59 | 1,6611207136 | 1,6642794824 | 0,0031587687 | 0,19% |
60 | 1,7370080258 | 1,7320508076 | 0,0049572182 | 0,29% |
61 | 1,8015318914 | 1,8040477553 | 0,0025158639 | 0,14% |
62 | 1,8874065642 | 1,8807264653 | 0,0066800989 | 0,36% |
63 | 1,9608540947 | 1,9626105055 | 0,0017564108 | 0,09% |
64 | 2,0592616947 | 2,0503038416 | 0,0089578531 | 0,44% |
65 | 2,1430961381 | 2,1445069205 | 0,0014107824 | 0,07% |
66 | 2,2571167455 | 2,2460367739 | 0,0110799716 | 0,49% |
67 | 2,3558194635 | 2,3558523658 | 0,0000329023 | 0,00% |
68 | 2,4620792981 | 2,4750868534 | 0,0130075554 | 0,53% |
69 | 2,6068564457 | 2,6050890647 | 0,0017673810 | 0,07% |
70 | 2,7338445118 | 2,7474774195 | 0,0136329076 | 0,50% |
71 | 2,9086860855 | 2,9042108777 | 0,0044752078 | 0,15% |
72 | 3,0966068440 | 3,0776835372 | 0,0189233068 | 0,61% |
73 | 3,2704830864 | 3,2708526185 | 0,0003695321 | 0,01% |
74 | 3,4630633646 | 3,4874144438 | 0,0243510793 | 0,70% |
75 | 3,7350103188 | 3,7320508076 | 0,0029595113 | 0,08% |
76 | 3,9831024743 | 4,0107809335 | 0,0276784592 | 0,69% |
77 | 4,3402911778 | 4,3314758743 | 0,0088153035 | 0,20% |
78 | 4,6728343111 | 4,7046301095 | 0,0317957983 | 0,68% |
79 | 5,1598511079 | 5,1445540160 | 0,0152970920 | 0,30% |
80 | 5,6293587144 | 5,6712818196 | 0,0419231052 | 0,74% |
81 | 6,3467099468 | 6,3137515147 | 0,0329584321 | 0,52% |
82 | 7,0627753134 | 7,1153697224 | 0,0525944090 | 0,74% |
83 | 8,2145617824 | 8,1443464280 | 0,0702153544 | 0,86% |
84 | 9,4420188415 | 9,5143644542 | 0,0723456127 | 0,76% |
85 | 11,6012216411 | 11,4300523028 | 0,1711693383 | 1,50% |
86 | 13,9690892768 | 14,3006662567 | 0,3315769799 | 2,32% |
87 | 19,2379608497 | 19,0811366877 | 0,1568241620 | 0,82% |
88 | 27,5277250976 | 28,6362532829 | 1,1085281853 | 3,87% |
89 | 59,5887437442 | 57,2899616308 | 2,2987821135 | 4,01% |
4. Výpočet arkustangenty pomocí algoritmu CORDIC
Výpočet arkustangenty se provádí poněkud odlišným způsobem než výše uvedený výpočet sinu, kosinu či tangenty, stále se však jedná o aplikaci velmi univerzálního principu, který CORDIC představuje. Využívá se zde takzvaný vektorový režim, ve kterém se – narozdíl od výše popsaného rotačního režimu – iterativně snažíme dosáhnout toho, aby se vynulovala hodnota uložená v registru y, tj. aby rotovaný vektor ležel na kladné či záporné horizontální poloose.
Výsledek běhu algoritmu CORDIC není v tomto případě uložen v registrech x nebo y (ty mají jiný význam), ale naopak v registru delta, který měl v rotačním režimu úlohu arbitru o směru rotace (ve vektorovém režimu tuto úlohu převzala hodnota v registru y, resp. znaménko hodnoty v tomto registru uložené).
Vstupem algoritmu jsou počáteční hodnoty x a y (ty byly u předchozích metod nulové), přičemž se počítá arctan(y/x). To je velmi praktické, protože takto je možné vypočítat i arkustangentu kladného a záporného nekonečna (1/0 resp. –1/0), což jsou legální operace (stejným způsobem tento problém řeší standardní céčkovská knihovní funkce atan2()). Demonstrační příklad na výpočet arkustangenty je, spolu s tabulkou výsledků, uveden v páté kapitole.
5. Druhý demonstrační příklad – výpočet arkustangenty
V této kapitole je uveden výpis demonstračního příkladu, který provádí výpočet arkustangenty na základě čitatele a jmenovatele zlomku, tj. provádí se stejná operace, jaká je představována céčkovskou funkcí atan2(). Po překladu a spuštění příkladu se vypočte tabulka arkustangent pro hodnoty z intervalu 0,0 – 1,0, které odpovídají úhlům 0° – 45° (tj. 0 – π/4).
// --------------------------------------------------------
// Výpočet hodnot funkce atan() pomocí iteračního algoritmu
// CORDIC.
// --------------------------------------------------------
#include <stdio.h>
#include <math.h>
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
// maximální počet iterací při běhu algoritmu
#define MAX_ITER 20
// "zesílení" při rotacích
#define K 0.6073
// tabulka arkustangentu úhlů
double atans[MAX_ITER];
// tabulka záporných celočíselných mocnin hodnoty 2
double pows[MAX_ITER];
// naplnění tabulek atans[] a pows[]
void createTables(void)
{
int i;
for (i=0; i<MAX_ITER; i++) {
double p=pow(2.0, -i);
atans[i]=atan(p);
pows[i]=p;
}
}
// výpočet funkce atan() pro zadané souřadnice x, y
double atan_cordic(double y, double x)
{
int i;
double x0=x; // nastavení počátečních podmínek
double y0=y;
double xn;
double delta=0.0;
for (i=0; i<MAX_ITER; i++) { // iterační smyčka
if (y0>0) { // kladná polorovina => rotace doleva
xn=x0+y0*pows[i];
y0-=x0*pows[i];
delta+=atans[i];
}
else { // záporná polorovina => rotace doprava
xn=x0-y0*pows[i];
y0+=x0*pows[i];
delta-=atans[i];
}
x0=xn;
}
return delta; // výsledek je uložen v akumulátoru úhlu
}
int main(void)
{
double i;
createTables();
for (i=0.0; i<1.05; i+=0.05) { // výpočetní smyčka
double atanval; // vypočtená hodnoty
double atanerr; // absolutní chyba
double atanfloat;
atanval=atan_cordic((double)i, 1.0)*180.0/M_PI; // výpočet funkce atan
atanfloat=atan(i)*180.0/M_PI;
atanerr=fabs(atanval-atanfloat); // výpočet absolutní chyby
// tisk výsledků
printf("%3.2f\t%14.10f\t%14.10f\t%12.10f\t%8.3f%%\n",
i,
atanval,
atanfloat,
atanerr,
atanfloat==0 ? 0:100.0*atanerr/atanfloat);
}
// důkaz, že atan se spočte i pro nekonečno, tj. pravý úhel:
printf("\natan nekonecna: %f\n", atan_cordic(1.0, 0.0)*180.0/M_PI);
return 0;
}
// finito
V následující tabulce je ukázán výstup z předchozího programu spolu s absolutními a relativními chybami oproti hodnotě vypočtené pomocí standardní céčkovské funkce atan().
Poměr x:y | arctan() podle CORDICu | arctan() podle FPU | absolutní chyba | relativní chyba |
---|---|---|---|---|
0,00 | 0,0000245652 | 0,0000000000 | 0,0000245652 | 0,000% |
0,05 | 2,8624810370 | 2,8624052261 | 0,0000758109 | 0,003% |
0,10 | 5,7106811868 | 5,7105931375 | 0,0000880493 | 0,002% |
0,15 | 8,5307849790 | 8,5307656099 | 0,0000193691 | 0,000% |
0,20 | 11,3099067631 | 11,3099324740 | 0,0000257109 | 0,000% |
0,25 | 14,0362661842 | 14,0362434679 | 0,0000227162 | 0,000% |
0,30 | 16,6993302827 | 16,6992442340 | 0,0000860487 | 0,001% |
0,35 | 19,2900922095 | 19,2900462192 | 0,0000459903 | 0,000% |
0,40 | 21,8013622439 | 21,8014094864 | 0,0000472424 | 0,000% |
0,45 | 24,2277345631 | 24,2277453180 | 0,0000107549 | 0,000% |
0,50 | 26,5651577003 | 26,5650511771 | 0,0001065233 | 0,000% |
0,55 | 28,8107759334 | 28,8107937430 | 0,0000178096 | 0,000% |
0,60 | 30,9638184479 | 30,9637565321 | 0,0000619158 | 0,000% |
0,65 | 33,0238878305 | 33,0238675558 | 0,0000202747 | 0,000% |
0,70 | 34,9919291984 | 34,9920201986 | 0,0000910002 | 0,000% |
0,75 | 36,8699222111 | 36,8698976458 | 0,0000245652 | 0,000% |
0,80 | 38,6598324994 | 38,6598082541 | 0,0000242453 | 0,000% |
0,85 | 40,3645231324 | 40,3645365731 | 0,0000134407 | 0,000% |
0,90 | 41,9872306433 | 41,9872124958 | 0,0000181475 | 0,000% |
0,95 | 43,5312567540 | 43,5311992856 | 0,0000574684 | 0,000% |
1,00 | 44,9999061705 | 45,0000000000 | 0,0000938295 | 0,000% |
6. Výpočet délky vektoru pomocí algoritmu CORDIC
Délka vektoru se kupodivu počítá naprosto stejným způsobem jako funkce arkustangenty. Je to z toho důvodu, že se arkustangenta iterativně vypočítá pootočením vstupního vektoru do polohy, ve které má y-ovou souřadnici nulovou. To však logicky znamená, že jeho x-ová souřadnice odpovídá délce vektoru, protože platí:
d=sqrt(x2+y2)=sqrt(x2+0)=sqrt(x2)=x
Proto se výše uvedená funkce pro výpočet arkustangenty může upravit na výpočet délky vektoru a to tak, že se výsledná hodnota xi (vzniklá po i iteracích) vynásobí konstantou Ki stejným způsobem, jaký jsme prováděli u výpočtů funkcí sin() a cos() v předchozím pokračování tohoto seriálu.
Vlastnosti CORDICu, díky které je možné jednoduše spočítat délku vektoru, není široce známa, proto některé FPU pro tuto činnost ani neobsahují instrukci, což je škoda, zejména při práci s grafikou, kde se délky velmi často počítají a je pro ně nutné použít dvojici násobení, jedno sečítání a k tomu ještě druhou odmocninu, tj. poměrně zdlouhavé a složité operace.
7. Třetí demonstrační příklad – výpočet délky vektoru
Po překladu a spuštění třetího demonstračního příkladu se zobrazí tabulka s délkami vektorů, jejichž souřadnice postupně nabývají hodnot od nuly do desíti. Všimněte si, že přesnost výpočtů je poměrně velká, například pro vektor (6,8) je přesně vypočtena délka 10.
// --------------------------------------------------------
// Výpočet velikosti vektoru pomocí iteračního algoritmu
// CORDIC.
// --------------------------------------------------------
#include <stdio.h>
#include <math.h>
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
// maximální počet iterací při běhu algoritmu
#define MAX_ITER 20
// "zesílení" při rotacích
#define K 0.6073
// tabulka arkustangentu úhlů
double atans[MAX_ITER];
// tabulka záporných celočíselných mocnin hodnoty 2
double pows[MAX_ITER];
// naplnění tabulek atans[] a pows[]
void createTables(void)
{
int i;
for (i=0; i<MAX_ITER; i++) {
double p=pow(2.0, -i);
atans[i]=atan(p);
pows[i]=p;
}
}
// výpočet velikosti vektoru pomocí algoritmu CORDIC
double mag_cordic(double y, double x)
{
int i;
double x0=x; // nastavení počátečních podmínek
double y0=y;
double xn;
double delta=0.0;
for (i=0; i<MAX_ITER; i++) { // iterační smyčka
if (y0>0) { // kladná polorovina => rotace doleva
xn=x0+y0*pows[i];
y0-=x0*pows[i];
delta+=atans[i];
}
else { // záporná polorovina => rotace doprava
xn=x0-y0*pows[i];
y0+=x0*pows[i];
delta-=atans[i];
}
x0=xn;
}
return x0*K;
}
int main(void)
{
double x, y;
createTables();
printf("%f\n", mag_cordic(3, 4)); // výpočet Pythagorova trojúhelníka
for (y=0.0; y<=10.0; y+=1.0) { // tabulka velikostí různých vektorů
for (x=0.0; x<=10.0; x+=1.0) {
printf("%5.2f ", mag_cordic(x,y));
}
putchar('\n');
}
return 0;
}
// finito
d(x,y) | 0,00 | 1,00 | 2,00 | 3,00 | 4,00 | 5,00 | 6,00 | 7,00 | 8,00 | 9,00 | 10,00 |
---|---|---|---|---|---|---|---|---|---|---|---|
0,00 | 0,00 | 1,00 | 2,00 | 3,00 | 4,00 | 5,00 | 6,00 | 7,00 | 8,00 | 9,00 | 10,00 |
1,00 | 1,00 | 1,41 | 2,24 | 3,16 | 4,12 | 5,10 | 6,08 | 7,07 | 8,06 | 9,06 | 10,05 |
2,00 | 2,00 | 2,24 | 2,83 | 3,61 | 4,47 | 5,39 | 6,33 | 7,28 | 8,25 | 9,22 | 10,20 |
3,00 | 3,00 | 3,16 | 3,61 | 4,24 | 5,00 | 5,83 | 6,71 | 7,62 | 8,54 | 9,49 | 10,44 |
4,00 | 4,00 | 4,12 | 4,47 | 5,00 | 5,66 | 6,40 | 7,21 | 8,06 | 8,94 | 9,85 | 10,77 |
5,00 | 5,00 | 5,10 | 5,39 | 5,83 | 6,40 | 7,07 | 7,81 | 8,60 | 9,43 | 10,30 | 11,18 |
6,00 | 6,00 | 6,08 | 6,33 | 6,71 | 7,21 | 7,81 | 8,49 | 9,22 | 10,00 | 10,82 | 11,66 |
7,00 | 7,00 | 7,07 | 7,28 | 7,62 | 8,06 | 8,60 | 9,22 | 9,90 | 10,63 | 11,40 | 12,21 |
8,00 | 8,00 | 8,06 | 8,25 | 8,54 | 8,94 | 9,43 | 10,00 | 10,63 | 11,31 | 12,04 | 12,81 |
9,00 | 9,00 | 9,06 | 9,22 | 9,49 | 9,85 | 10,30 | 10,82 | 11,40 | 12,04 | 12,73 | 13,45 |
10,00 | 10,00 | 10,05 | 10,20 | 10,44 | 10,77 | 11,18 | 11,66 | 12,21 | 12,81 | 13,45 | 14,14 |
8. Převod z kartézských do polárních souřadnic pomocí algoritmu CORDIC
Vzhledem k tomu, že převod z kartézských souřadnic do souřadnic polárních vyžaduje spočtení úhlu vektoru a jeho délky (popř. úhlu a délky spojnice bodu s počátkem souřadné soustavy), je na tomto místě možné říci, že převod již máme vyřešen, protože jediným iteračním postupem CORDICu vyjádříme jak délku vektoru (ta je uložena v registru x), tak i jeho úhel (ten je uložen v registru delta). Demonstrační příklad na převod z kartézských souřadnic do souřadnic polárních zde proto nebudu uvádět, čtenář může „spojit“ obě výše uvedené céčkovské funkce atan_cordic() a mag_cordic() do funkce jediné a výsledkem bude zmíněná konverzní (mapovací) funkce.
9. Obsah dalšího pokračování tohoto seriálu
V následujícím pokračování tohoto seriálu konečně obrátíme svoji pozornost na formát pevné řádové binární čárky, protože si podrobně popíšeme čtyři základní způsoby uložení čísel v tomto formátu, včetně vysvětlení kódování záporných čísel. Také si popíšeme, jakým způsobem je možné implementovat základní matematické operace s hodnotami uloženými ve formátu pevné řádové binární čárky.