很久不寫博客了。第一次寫博客是在04年,最近的一次還是在大學時,在學校時,甚至還有過自己去買虛擬主機搭WordPress寫博客的經歷。現在工作時間越長,越發現積累的重要性。那么就從這里開始吧,重新開始寫博客。
最近打算寫小算法,里面需要用到一些復數運算。貼一點復數運算的C語言實現代碼。都是些很簡單的東西。
包括以下運算:
復數加法、復數減法、復數乘法、復數除法、復數取模、復指數運算、復數取相角、模與相角合成復位。本人專業本職做硬件的,寫程序沒受過專業訓練,勿吐槽。

1 /*file ComplexCalculation.h 2 *author Vincent Cui 3 *e-mail whcui1987@163.com 4 *version 0.1 5 *data 20-Oct-2014 6 *brief 用於復數運算的一些函數頭和定義 7 */ 8 9 10 11 #ifndef _COMPLEXCALCULATION_H_ 12 #define _COMPLEXCALCULATION_H_ 13 14 #define ASSERT_ENABLE 1 15 16 #define IS_COMPLEX_DIVISOR_CORRENT(DIVISOR_REAL, DIVISOR_IMAG) ((DIVISOR_REAL != 0) || (DIVISOR_IMAG != 0)) 17 18 typedef double mathDouble; 19 typedef unsigned char mathUint_8; 20 typedef unsigned short int mathUint_16; 21 typedef unsigned int mathUint_32; 22 23 24 typedef struct _ReDefcomplex 25 { 26 mathDouble Real; 27 mathDouble Imag; 28 }complexType; 29 30 31 complexType complexAdd(complexType a, complexType b); 32 complexType complexSubtract(complexType minuend, complexType subtrahend); 33 complexType complexMultiply(complexType a, complexType b); 34 complexType complexDivision(complexType dividend, complexType divisor); 35 mathDouble complexAbs(complexType a); 36 mathDouble complexAngle(complexType a); 37 complexType complexByAbsAngle(mathDouble r, mathDouble theta); 38 complexType complexExp(complexType a); 39 40 #if ASSERT_ENABLE 41 #define assert_param(expr) ((expr) ? (void)0 : assert_failed((mathUint_8 *)__FILE__, __LINE__)) 42 void assert_failed(mathUint_8* file, mathUint_32 line); 43 #else 44 #define assert_param(expr) ((void)0) 45 #endif 46 47 48 49 #endif

1 /*file ComplexCalculation.c 2 *author Vincent Cui 3 *e-mail whcui1987@163.com 4 *version 0.1 5 *data 20-Oct-2014 6 *brief 用於復數運算的一些函數 7 */ 8 9 10 #include "ComplexCalculation.h" 11 #include "math.h" 12 #include "stdio.h" 13 14 15 /*函數名:complexAdd 16 *說明:復數加法 17 *輸入:a,b兩個復數 18 *輸出: 19 *返回:a + b 20 *調用: 21 *其它: 22 */ 23 complexType complexAdd(complexType a, complexType b) 24 { 25 complexType result; 26 27 result.Real = a.Real + b.Real; 28 result.Imag = a.Imag + b.Imag; 29 30 return result; 31 } 32 33 /*函數名:complexSubtract 34 *說明:復數減法 35 *輸入:minuend被減數,subtrahend減數 36 *輸出: 37 *返回:a - b 38 *調用: 39 *其它: 40 */ 41 complexType complexSubtract(complexType minuend, complexType subtrahend) 42 { 43 complexType result; 44 45 result.Real = minuend.Real - subtrahend.Real; 46 result.Imag = minuend.Imag - subtrahend.Imag; 47 48 return result; 49 } 50 51 /*函數名:complexMultiply 52 *說明:復數乘法 53 *輸入:a,b兩個復數 54 *輸出: 55 *返回:a * b 56 *調用: 57 *其它: 58 */ 59 complexType complexMultiply(complexType a, complexType b) 60 { 61 complexType result; 62 63 result.Real = a.Real * b.Real - a.Imag * b.Imag; 64 result.Imag = a.Imag * b.Real + a.Real * b.Imag; 65 66 return result; 67 } 68 69 70 /*函數名:complexDivision 71 *說明:復數除法 72 *輸入:dividend被除數,divisor除數 73 *輸出: 74 *返回:a / b 75 *調用: 76 *其它:divisor的實部和虛部不能同時為0 77 */ 78 complexType complexDivision(complexType dividend, complexType divisor) 79 { 80 complexType result; 81 82 /*斷言,被除數的實部和虛部不能同時為零*/ 83 assert_param(IS_COMPLEX_DIVISOR_CORRENT(divisor.Real, divisor.Imag)); 84 85 result.Real = (mathDouble)(dividend.Real * divisor.Real + dividend.Imag * divisor.Imag) / \ 86 (divisor.Real * divisor.Real + divisor.Imag * divisor.Imag); 87 result.Imag = (mathDouble)(dividend.Imag * divisor.Real - dividend.Real * divisor.Imag) / \ 88 (divisor.Real * divisor.Real + divisor.Imag * divisor.Imag); 89 return result; 90 } 91 92 /*函數名:complexAbs 93 *說明:復數取模 94 *輸入:a復數 95 *輸出: 96 *返回:復數的模 97 *調用: 98 *其它: 99 */ 100 mathDouble complexAbs(complexType a) 101 { 102 return (sqrt( pow(a.Real,2) + pow(a.Imag,2) )); 103 } 104 105 106 /*函數名:complexAngle 107 *說明:復數取相角 108 *輸入:a復數 109 *輸出: 110 *返回:復數的相角 111 *調用: 112 *其它: 113 */ 114 mathDouble complexAngle(complexType a) 115 { 116 /*是atan2而非atan,(-PI,PI] */ 117 return (atan2(a.Imag, a.Real)); 118 } 119 120 /*函數名:complexByAbsAngle 121 *說明:通過模和相角合成復數 122 *輸入:r 模, theta 相角 123 *輸出: 124 *返回:復數 125 *調用: 126 *其它: 127 */ 128 complexType complexByAbsAngle(mathDouble r, mathDouble theta) 129 { 130 complexType tmp_1,tmp_2; 131 132 tmp_1.Real = 0; 133 tmp_1.Imag = theta; 134 tmp_2 = complexExp(tmp_1); 135 tmp_2.Real *= r; 136 tmp_2.Imag *= r; 137 138 return tmp_2; 139 } 140 141 /*函數名:complexExp 142 *說明:復指數運算 143 *輸入:a 復指數 144 *輸出: 145 *返回:e的a次方 146 *調用: 147 *其它:使用歐拉公式 e^(jw) = cos(w) + j * sin(w) 148 */ 149 complexType complexExp(complexType a) 150 { 151 complexType result; 152 153 result.Real = exp(a.Real) * cos(a.Imag); 154 result.Imag = exp(a.Real) * sin(a.Imag); 155 156 return result; 157 } 158 159 160 #if ASSERT_ENABLE 161 /*函數名:assert_failed 162 *說明:斷言函數 163 *輸入: 164 *輸出:打印出錯的位置 165 *返回: 166 *調用: 167 *其它: 168 */ 169 void assert_failed(mathUint_8* file, mathUint_32 line) 170 { 171 printf("Assert Error in File: %s \r\nLine: %d \r\n",file,line); 172 } 173 174 #endif

1 #include "ComplexCalculation.h" 2 #include "stdio.h" 3 4 int main(void) 5 { 6 complexType a,b,c; 7 a.Imag = 0.5; 8 a.Real = 2.5; 9 b.Real = 1; 10 b.Imag = -5; 11 12 c = complexAdd(a,b); 13 printf("complexAdd: c.Real %f, c.Imag %f \r\n",c.Real,c.Imag); 14 c = complexSubtract(a,b); 15 printf("complexSubtract: c.Real %f, c.Imag %f \r\n",c.Real,c.Imag); 16 c = complexMultiply(a,b); 17 printf("complexMultiply: c.Real %f, c.Imag %f \r\n",c.Real,c.Imag); 18 c = complexDivision(a,b); 19 printf("complexDivision: c.Real %f, c.Imag %f \r\n",c.Real,c.Imag); 20 printf("Abs(c): %f\r\n",complexAbs(a)); 21 printf("Angle(c): %f\r\n",complexAngle(a)); 22 c = complexByAbsAngle(complexAbs(a),complexAngle(a)); 23 printf("complexByAbsAngle: a.Real %f, a.Imag %f \r\n",c.Real,c.Imag); 24 25 while(1); 26 }
下面是運行結果,在VS2012上運行的。
歡迎一起交流!
后面博客中我會寫一些數字信號處理運算的C語言實現。