CORDIC，也稱為 Volder 演演算法，是一個可以計算三角函式，簡單且有效率的演演算法，可以在任意進位制下運算，一般會每次計算一位數字。因此 CORDIC 屬於逐位計算（Digitbydigit）方法中的一個例子。 CORDIC 演演算法還有其他的名稱，像是圓形 CORDIC Jack E Volder、線性 CORDIC、雙曲線 CORDIC John Stephen Walther、及泛用雙曲線 CORDIC（GH CORDIC Yuanyong Luo et al）。用類似的方式也可以計算雙曲函式、平方根、乘法、除法、指數及對數等。 CORDIC 和一些名為「偽乘法」（pseudomultiplication）、「偽除法」（pseudodivision）及 factor combining 的方法，常用在沒有乘法器的應用（像是簡單的微控制器以及 FPGA），其中會用到的運算是加法、減法、位元移位及查詢表。這些演算法可歸類在「移位和相加」（shiftandadd）演演算法中。在電腦科學中，若 CPU 沒有硬體的乘法器，常會用 CORDIC 來實現浮點數運算。 歷史 英國數學家早在 1624 年時就已發現此演算法，後來 Robert Flower 也在 1771 年時發現，不過後來是因為低複雜度的有限狀態 CPU，才針對 CORDIC 作較進一步的最佳化。 CORDIC 是在 1956 年問世，是由康維爾空氣電子部門的發現，一開始是因為要取代導航電腦上面的類比式解角器（resolver），更換成更準確而實時的數位方案。因此，有時也會將 CORDIC 稱為數位解角器（digital resolver）。 Volder 的研究，是因為 1946 年版 CRC 化學和物理手冊中的公式而得到靈感： begin align K_n R sin theta pm varphi R sin theta pm 2n R cos theta K_n R cos theta pm varphi R cos theta mp 2n R sin theta end align 其中 varphi 是使 tan varphi 2n 成立的值，且 K_n sqrt 1 22n。 他的研究最後產生了一個內部的技術報告，提到用 CORDIC 演演算法來求解正弦及餘弦函式，以及一個實現此功能的原型電腦。報告中也提到用修改版的 CORDIC 演演算法計算雙曲函式、座標旋轉、對數及指數的可能性。用 CORDIC 來進行乘法和除法運算的想法也是在此時形成。依照 CORDIC 演演算法的原則，Volder 的同事 Dan H Daggett 發展了在二進位以及二進碼十進數（BCD）之間轉換的演演算法。 應用 CORDIC 用簡單的移位和相加運算來處理像是三角函式、雙曲函式、對數函式、實數及複數乘法、除法、方根計算、線性系統求解、特徵值估測、奇異值分解、QR 分解等。因此，CORDIC 可以用在許多的應用中，像是訊號處理、影像處理、通訊系統、機器人學及三維計算機圖形等。 硬體 若沒有硬體乘法器的話，CORDIC 一般會比其他演算法要快很多，若是用 FPGA 或 ASIC 的話，使用的邏輯閘也會少很多。 CORDIC 是 FPGA 開發應用程式（像是 Xilinx 的 Vivado）中的標準半導體 IP 核，而不是使用特殊函式的冪級數實現，其原因是 CORDIC IP 的通用性，CORDIC 可以計算許多不同的函式，而為特定函式開發的乘法器只能計算特定的函式。 另一方面，若有硬體乘法器（例如 DSP），查表法及冪級數會比 CORDIC 快很多。近年來，CORDIC 演演算法常用在生醫應用中，尤其是用 FPGA 實現的應用。 使用泰勒級數的問題是此方法可以產生小的絕對誤差，但其中沒有良態的相對誤差。其他多項式近似法，例如，可以同時控制這二種的誤差。 軟體 在 CPU 只有整數運算的古老系統中，會將 CORDIC 放在其 IEEE 754 函式庫的一部份。現代的通用 CPU 已有浮點運算暫存器，也有加法、減法、乘法、除法、三角函式、平方根、一般對數、自然對數等，幾乎沒有用到 CORDIC 的場合。只有一些有特殊安全性或是時間要求的應用程式才會用到 CORDIC。 運作模式 旋轉模式 CORDIC 可以用來計算許多不同的函式。以下說明如何在旋轉模式（rotation mode）下的 CORDIC 計算角度的正弦函式和餘弦函式，假設角度以弧度的定點格式表示。要找到一個角度 beta 的正弦函式和餘弦函式，可以在單位圓上找到對應角度的 y 座標和座標。利用 CORDIC，會從以下的向量 v_0 開始： v_0 begin bmatrix 1 0 end bmatrix 在第一次的迭代時，向量逆時針轉 45，得到向量 v_1。接著繼續的迭代，每一次的角度漸漸變小，旋轉方向可能順時針，也可能逆時針，直到得到想要的角度為止。每一次的角度為 gamma_i arctan 2i，其中 i 0 1 2 dots。 若以更正式的方式表示，每一次的迭代就是一次旋轉，也就是將向量 v_i 乘以旋轉矩陣 R_i： v_i1 R_i v_i 旋轉矩陣為 R_i begin bmatrix cos gamma_i sin gamma_i sin gamma_i cos gamma_i end bmatrix 利用以下兩個三角恆等式： begin align cos gamma_i frac 1sqrt 1 tan2 gamma_i sin gamma_i frac tan gamma_isqrt 1 tan2 gamma_i end align 旋轉矩陣變成 R_i frac 1sqrt 1 tan2 gamma_i begin bmatrix 1 tan gamma_i tan gamma_i 1 end bmatrix 旋轉向量 v_i1 R_i v_i 就會變成下式 begin bmatrix x_i1 y_i1 end bmatrix frac 1sqrt 1 tan2 gamma_i begin bmatrix 1 tan gamma_i tan gamma_i 1 end bmatrix begin bmatrix x_i y_i end bmatrix 其中 x_i 和 y_i 是 v_i 的分量，若將角度 gamma_i 限制在使 tan gamma_i pm 2i 的值，和 tangent 的乘法就以變成乘（或除）2 的冪次，在數位電腦硬體中可以快速的用位元右移或左移來計算。因此上法會變成 begin bmatrix x_i1 y_i1 end bmatrix K_i begin bmatrix 1 sigma_i 2i sigma_i 2i 1 end bmatrix begin bmatrix x_i y_i end bmatrix 其中 K_i frac 1sqrt 1 22i 且 sigma_i 是用來判斷旋轉方向的。若角度 gamma_i 為正，則 sigma_i 為 1，否則則為1。 所有的 K_i 因子可以在迭代過程中忽略，最後再一次乘以 K n 因子即可： K n prod_i0n1 K_i prod_i0n1 frac 1sqrt 1 22i 此數可以事先計算好存在表格中，若迭代次數是固定的，只需計算一個常數且儲存即可，甚至此修正也可以事先進行，將常數先乘以 v_0，可以節省一次乘法。另外，可以注意到 K lim_n to infty K n approx 06072529350088812561694 因此可以簡化演演算法的複雜度。有些應用會避免修正 K，因此此演演算法本身會帶一個增益 A： A frac 1K lim_n to infty prod_i0n1 sqrt 1 22i approx 164676025812107 在夠多次的迭代後，向量的角度會接近想要的角度 beta。以一般的應用來說，40 次的迭代（n 40）已可以有小數 10 位的精度。 唯一未解決的問題是判斷每一次迭代要順時針旋轉或逆時針旋轉（選擇 sigma 的值）。這可以記錄每一次旋轉的角度，從還需要旋轉的角度中減去此一角度，會得到下一個還需要旋轉的角度 beta。若 beta_n1 為正，需要順時針旋轉，否則，就需要順時針旋轉： beta_0 beta beta_i1 beta_i sigma_i gamma_i quad gamma_i arctan 2i gamma_n 的值需要事先計算且記錄下來。不過若是小角度，根據小角度近似，在定點數下可得 arctan gamma_n gamma_n，因此可以節省儲存用的空間。 如以上所述，角度 beta 的正弦函式為其 y 坐標，餘弦函式為其 x 坐標。 向量模式 上述旋轉模式的演演算法，是旋轉原來位在 x 軸上的單位向量。但此演演算法可以用來旋轉角度在pi 2 及 pi 2 之間的任意向量，旋轉的方向則依 beta_i 的正負號決定。 向量模式下的演演算法和旋轉模式略有不同。其啟始向量的 x 坐標要為正值，y 坐標則為任意值。持續轉動的目的是將向量旋轉到 x 軸（因此 y 座標為 0）。每一步裡的旋轉方向會由 y 的值決定。beta_i 的最終值包括了總旋轉角度。x 的最終值是原向量的大小，再乘以 K。因此，可以看出向量模式可以進行直角坐標到極坐標的轉換。 實現 Java 的 Math 類別中有 scalb double xint scale 方法可以實現二進位的移位，C 語言有 ldexp 函式，x86 處理器有 fscale 浮點運算。 軟體範例（Python） from math import atan2 sqrt sin cos radians ITERS 16 theta_table atan2 1 2i for i in range ITERS def compute_K n Compute K n for n ITERS This could also be stored as an explicit constant if ITERS above is fixed k 10 for i in range n k 1 sqrt 1 2 2 i return k def CORDIC alpha n K_n compute_K n theta 00 x 10 y 00 P2i 1 This will be 2i in the loop below for arc_tangent in theta_table sigma 1 if theta alpha else 1 theta sigma arc_tangent x y x sigma y P2i sigma P2i x y P2i 2 return x K_n y K_n if __name__ __main__ Print a table of computed sines and cosines from 90 to 90 in steps of 15 comparing against the available math routines print x sin x diff sine cos x diff cosine for x in range 90 91 15 cos_x sin_x CORDIC radians x ITERS print fx051f sin_x8f sin_xsin radians x8f cos_x8f cos_xcos radians x8f 輸出 python cordicpy x sin x diff sine cos x diff cosine 900 100000000 000000000 000001759 000001759 750 096592181 000000402 025883404 000001499 600 086601812 000000729 050001262 000001262 450 070711776 000001098 070709580 000001098 300 050001262 000001262 086601812 000000729 150 025883404 000001499 096592181 000000402 000 000001759 000001759 100000000 000000000 150 025883404 000001499 096592181 000000402 300 050001262 000001262 086601812 000000729 450 070709580 000001098 070711776 000001098 600 086601812 000000729 050001262 000001262 750 096592181 000000402 025883404 000001499 900 100000000 000000000 000001759 000001759 硬體範例 實現 CORDIC 需要的邏輯閘大約和乘法器相當，兩者都是用位元移位和加法所組合的。要選擇乘法器或是 CORDIC 會隨應用而定。若複數以其實部和虛部表示（直角座標），複數乘法會需要進行四次的乘法。但若複數以極座標表示，只要一個 CORDIC 即可處理，這更適合用在其乘積的量值不重要的應用（例如將向量和單位圓上的向量相乘的情形）。在之類的通訊相關電路中，常會用到 CORDIC。 雙重迭代 CORDIC 在 Vladimir Baykov 的二篇文獻中，曾經提到用「雙重迭代」（double iterations）來實現反正弦函式、反餘弦函式、自然對數、指數函式以及雙曲函式。雙重迭代中的作法和傳統的 CORDIC 演演算法不同，傳統的 CORDIC 演演算法中，迭代變數會在每次迭代時加一。但在雙重迭代中，迭代變數會先重複一次，然後才加一。因此雙重迭代 CORDIC 演演算法的迭代變數會是 i 0 0 1 1 2 2dots，而傳統 CORDIC 演演算法的迭代變數是 i 0 1 2dots。雙重迭代法保證方法的收斂，不過其引數的有效範圍會變化。 針對 R 進位制數字系統中，通用的 CORDIC 收斂問題，可以證明針對正弦、餘弦及反正切函式，每一個 i（i 0 或 1 到 n，其中 n 是位數）進行 R 1 次迭代就可以保證收斂。若是自然對數、指數、雙曲正弦、雙曲餘弦及雙曲反正切函式，每一個 i 需要進行 R 次迭代。若是反正弦函式及反餘弦函式，每一個 i 需要進行 2 R 1 次的迭代。 若是雙曲反正弦及雙曲反餘弦函式，每一個 i 需要進行 2R 次的迭代。 相關演演算法 CORDIC 屬於「移位及加法」（shiftandadd）的演演算法，就像 Henry Briggs 文獻提到的對數和指數演演算法一樣。也是可以計算許多基本函式的移位及加法演演算法，是複數平面下對數和指數演演算法的推廣。BKM 可以計算實數角度 x（以弧度表示）的正弦和餘弦，其方式是計算 0ix 的指數，也就是 operatorname cisx cos x i sin x。BKM 演演算法比 CORDIC 要複雜一些，但其優點是不需考慮比例因子（K）。 相關條目 IEEE 754 浮點運算器 參考資料 外部連結 Category 求根演算法 Category 計算機算術 Category 數值分析 Category 三角學