ฉันจะทำงานกับจำนวนเชิงซ้อนใน C ได้อย่างไร? ฉันเห็นว่ามีcomplex.h
ไฟล์ส่วนหัว แต่ไม่ได้ให้ข้อมูลเกี่ยวกับวิธีการใช้งานมากนัก วิธีการเข้าถึงส่วนจริงและจินตนาการอย่างมีประสิทธิภาพ? มีฟังก์ชันดั้งเดิมในการรับโมดูลและเฟสหรือไม่?
ฉันจะทำงานกับจำนวนเชิงซ้อนใน C ได้อย่างไร? ฉันเห็นว่ามีcomplex.h
ไฟล์ส่วนหัว แต่ไม่ได้ให้ข้อมูลเกี่ยวกับวิธีการใช้งานมากนัก วิธีการเข้าถึงส่วนจริงและจินตนาการอย่างมีประสิทธิภาพ? มีฟังก์ชันดั้งเดิมในการรับโมดูลและเฟสหรือไม่?
คำตอบ:
รหัสนี้จะช่วยคุณได้และค่อนข้างอธิบายตัวเองได้:
#include <stdio.h> /* Standard Library of Input and Output */
#include <complex.h> /* Standard Library of Complex Numbers */
int main() {
double complex z1 = 1.0 + 3.0 * I;
double complex z2 = 1.0 - 4.0 * I;
printf("Working with complex numbers:\n\v");
printf("Starting values: Z1 = %.2f + %.2fi\tZ2 = %.2f %+.2fi\n", creal(z1), cimag(z1), creal(z2), cimag(z2));
double complex sum = z1 + z2;
printf("The sum: Z1 + Z2 = %.2f %+.2fi\n", creal(sum), cimag(sum));
double complex difference = z1 - z2;
printf("The difference: Z1 - Z2 = %.2f %+.2fi\n", creal(difference), cimag(difference));
double complex product = z1 * z2;
printf("The product: Z1 x Z2 = %.2f %+.2fi\n", creal(product), cimag(product));
double complex quotient = z1 / z2;
printf("The quotient: Z1 / Z2 = %.2f %+.2fi\n", creal(quotient), cimag(quotient));
double complex conjugate = conj(z1);
printf("The conjugate of Z1 = %.2f %+.2fi\n", creal(conjugate), cimag(conjugate));
return 0;
}
ด้วย:
creal(z1)
:รับส่วนจริง (สำหรับลูกลอยcrealf(z1)
สำหรับคู่ยาวcreall(z1)
)
cimag(z1)
:รับส่วนจินตภาพ (สำหรับลอยcimagf(z1)
สำหรับคู่ยาวcimagl(z1)
)
อีกจุดที่สำคัญที่ต้องจำเมื่อทำงานกับตัวเลขที่ซับซ้อนเป็นฟังก์ชั่นที่ชอบcos()
, exp()
และsqrt()
ต้องถูกแทนที่ด้วยรูปแบบที่ซับซ้อนของพวกเขาเช่นccos()
, ,cexp()
csqrt()
double complex
? นี่เป็นส่วนขยายภาษาหรือเวทมนตร์มาโคร?
complex
เป็นประเภท c99 มาตรฐาน (ภายใต้ประทุนของ GCC เป็นนามแฝงของประเภท _Complex)
complex
ไม่ใช่ประเภท เป็นมาโครที่ขยายไปถึง_Complex
ซึ่งเป็นตัวระบุประเภทแต่ไม่ใช่ประเภทด้วยตัวมันเอง ประเภทที่ซับซ้อนfloat _Complex
, และdouble _Complex
long double _Complex
ประเภทที่ซับซ้อนอยู่ในภาษา C ตั้งแต่มาตรฐาน C99 ( -std=c99
ตัวเลือกของ GCC) คอมไพเลอร์บางตัวอาจใช้ประเภทที่ซับซ้อนแม้ในโหมดก่อนหน้านี้ แต่นี่ไม่ใช่ส่วนขยายมาตรฐานและไม่ใช่แบบพกพา (เช่น IBM XL, GCC อาจเป็น intel, ... )
คุณสามารถเริ่มต้นจากhttp://en.wikipedia.org/wiki/Complex.h - ให้คำอธิบายฟังก์ชันจาก complex.h
คู่มือนี้http://pubs.opengroup.org/onlinepubs/009604499/basedefs/complex.h.htmlยังให้ข้อมูลบางอย่างเกี่ยวกับมาโคร
หากต้องการประกาศตัวแปรที่ซับซ้อนให้ใช้
double _Complex a; // use c* functions without suffix
หรือ
float _Complex b; // use c*f functions - with f suffix
long double _Complex c; // use c*l functions - with l suffix
ในการกำหนดค่าให้ซับซ้อนให้ใช้_Complex_I
มาโครจากcomplex.h
:
float _Complex d = 2.0f + 2.0f*_Complex_I;
(ที่จริงอาจมีปัญหากับ(0,-0i)
ตัวเลขและ NaN ในครึ่งเดียวของเชิงซ้อน)
โมดูลคือcabs(a)
/ cabsl(c)
/ cabsf(b)
; ส่วนหนึ่งที่แท้จริงคือจินตนาการมีcreal(a)
มีไว้สำหรับการโต้แย้งที่ซับซ้อนcimag(a)
carg(a)
หากต้องการเข้าถึง (อ่าน / เขียน) จริงโดยตรงคุณสามารถใช้ส่วนขยาย GCC ที่ไม่สามารถพกพาได้ นี้:
__real__ a = 1.4;
__imag__ a = 2.0;
float b = __real__ a;
(complex float) { r, i }
ยังสามารถใช้เพื่อตั้งค่าส่วนที่แยกจากกันของจำนวนและแยกกันได้ (อนุญาตให้ส่วนจริงเป็น INF ในขณะที่ส่วนจินตภาพเป็น NAN เป็นต้น) ซึ่งเป็นการหลีกเลี่ยงคีย์เวิร์ดเฉพาะ GCC แม้ว่าฉันจะไม่แน่ใจว่าเป็นแบบพกพาจริงหรือไม่
__STDC_NO_COMPLEX__
คอมไพเลอร์ก็อาจไม่ได้ถ้าพวกเขากำหนด อย่างไรก็ตามในทางปฏิบัติจะใช้กับคอมไพเลอร์หลัก
complex
_Complex
คุณอาจสนใจ "The New C Standard: An Economic and Cultural Commentary" ของ Derek M. (2008) หน้า 500 "ประเภทที่ซับซ้อน" people.ece.cornell.edu/land/courses/ece4760/…
Complex.h
#include <stdio.h> /* Standard Library of Input and Output */
#include <complex.h> /* Standart Library of Complex Numbers */
int main()
{
double complex z1 = 1.0 + 3.0 * I;
double complex z2 = 1.0 - 4.0 * I;
printf("Working with complex numbers:\n\v");
printf("Starting values: Z1 = %.2f + %.2fi\tZ2 = %.2f %+.2fi\n",
creal(z1),
cimag(z1),
creal(z2),
cimag(z2));
double complex sum = z1 + z2;
printf("The sum: Z1 + Z2 = %.2f %+.2fi\n", creal(sum), cimag(sum));
}
เพื่อความสะดวกอาจรวมtgmath.h
ไลบรารีสำหรับประเภทสร้างแมโคร สร้างชื่อฟังก์ชันเดียวกับเวอร์ชันคู่สำหรับตัวแปรทุกประเภท ยกตัวอย่างเช่นยกตัวอย่างเช่นมันกำหนดsqrt()
แมโครที่ขยายไปsqrtf()
, sqrt()
หรือsqrtl()
ฟังก์ชั่นขึ้นอยู่กับชนิดของการโต้แย้งที่มีให้
ดังนั้นเราไม่จำเป็นต้องจำชื่อฟังก์ชันที่เกี่ยวข้องสำหรับตัวแปรประเภทต่างๆ!
#include <stdio.h>
#include <tgmath.h>//for the type generate macros.
#include <complex.h>//for easier declare complex variables and complex unit I
int main(void)
{
double complex z1=1./4.*M_PI+1./4.*M_PI*I;//M_PI is just pi=3.1415...
double complex z2, z3, z4, z5;
z2=exp(z1);
z3=sin(z1);
z4=sqrt(z1);
z5=log(z1);
printf("exp(z1)=%lf + %lf I\n", creal(z2),cimag(z2));
printf("sin(z1)=%lf + %lf I\n", creal(z3),cimag(z3));
printf("sqrt(z1)=%lf + %lf I\n", creal(z4),cimag(z4));
printf("log(z1)=%lf + %lf I\n", creal(z5),cimag(z5));
return 0;
}
ความคิดของจำนวนเชิงซ้อนถูกนำมาใช้ในคณิตศาสตร์จากความจำเป็นในการคำนวณรากกำลังสองเชิงลบ แนวคิดจำนวนเชิงซ้อนถูกนำมาใช้โดยวิศวกรรมหลายสาขา
ปัจจุบันจำนวนเชิงซ้อนถูกใช้กันอย่างแพร่หลายในโดเมนวิศวกรรมขั้นสูงเช่นฟิสิกส์อิเล็กทรอนิกส์กลศาสตร์ดาราศาสตร์ ฯลฯ ...
ส่วนจริงและส่วนจินตภาพของตัวอย่างรากที่สองเชิงลบ:
#include <stdio.h>
#include <complex.h>
int main()
{
int negNum;
printf("Calculate negative square roots:\n"
"Enter negative number:");
scanf("%d", &negNum);
double complex negSqrt = csqrt(negNum);
double pReal = creal(negSqrt);
double pImag = cimag(negSqrt);
printf("\nReal part %f, imaginary part %f"
", for negative square root.(%d)",
pReal, pImag, negNum);
return 0;
}
เพื่อดึงส่วนที่แท้จริงของการแสดงออกจำนวนเชิงซ้อนใช้สัญกรณ์เป็นz
__real__ z
ในทำนองเดียวกันใช้__imag__
แอตทริบิวต์z
เพื่อแยกส่วนจินตภาพ
ตัวอย่างเช่น;
__complex__ float z;
float r;
float i;
r = __real__ z;
i = __imag__ z;
r คือส่วนจริงของจำนวนเชิงซ้อน "z" i คือส่วนจินตภาพของจำนวนเชิงซ้อน "z"