सी में जटिल संख्याओं के साथ कैसे काम करें?


122

मैं सी में जटिल संख्याओं के साथ कैसे काम कर सकता हूं? मैं देख रहा हूँ कि एक complex.hहेडर फ़ाइल है, लेकिन यह मुझे इस बारे में अधिक जानकारी नहीं देता है कि इसका उपयोग कैसे करें। वास्तविक और काल्पनिक भागों को एक कुशल तरीके से कैसे एक्सेस करें? क्या मॉड्यूल और चरण प्राप्त करने के लिए मूल कार्य हैं?


16
मैं C ++ के बजाय C का उपयोग कर रहा हूं क्योंकि मेरे पायथन कोड को बांधना आसान है।
चार्ल्स ब्रुनेट

जवाबों:


186

यह कोड आपकी मदद करेगा, और यह काफी आत्म-व्याख्यात्मक है:

#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()


12
यह क्या है double complex? क्या यह भाषा का विस्तार है या कुछ स्थूल जादू है?
कालमराशि

@ कैलेमरियस complexएक मानक c99 प्रकार है (GCC पर हुड के तहत, यह वास्तव में _Complex प्रकार का एक उपनाम है)।
स्निप

9
@ स्निप: complexएक प्रकार नहीं है। यह एक मैक्रो है जो विस्तार करता है _Complex, जो एक प्रकार का निर्दिष्ट है , लेकिन अपने आप में एक प्रकार नहीं है। जटिल प्रकार के होते हैं float _Complex, double _Complexऔर long double _Complex
कीथ थॉम्पसन

3
यह केवल जीसीसी नहीं है, यह मानक में परिभाषित किया गया है कि _Complex एक प्रकार का विनिर्देशक है और complex.h में एक जटिल मैक्रो है जो _Complex तक फैलता है। वही _Bool और stdbool.h के लिए जाता है।
jv110

40

C99 मानक के बाद से जटिल प्रकार C भाषा में हैं (-std=c99 जीसीसी का विकल्प) के । कुछ कंपाइलर जटिल प्रकारों को और अधिक पहले के मोड में भी लागू कर सकते हैं, लेकिन यह गैर-मानक और गैर-पोर्टेबल एक्सटेंशन (जैसे IBM XL, GCC, इंटेल, हो सकता है ...) है।

आप http://en.wikipedia.org/wiki/Complex.h से शुरू कर सकते हैं - यह जटिल से कार्यों का विवरण देता है।

यह नियमावली http://pubs.opengroup.org/onlinepubs/009604499/basedefs/complex.gov.in मैक्रोज़ के बारे में भी कुछ जानकारी देता है।

एक जटिल चर घोषित करने के लिए, का उपयोग करें

  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;

1
लगभग हर जटिल फ़ंक्शन को कंपाइलर द्वारा बिलियन फ़ंक्शन के रूप में कुशल तरीके से लागू किया जाएगा। बस आधुनिक संकलक का उपयोग करें और इसे अनुकूलन के कुछ गैर-शून्य स्तर दें।
ऑक्सएक्स

3
FYI करें, क्योंकि ओपी ने पायथन बाइंडिंग का उल्लेख किया है, जब पायथन के साथ काम करते हुए मैं C89 से चिपके रहने की कोशिश करता हूं (चूंकि पायथन का बाकी कोड C89 है, और यदि आप चाहते हैं कि आपका एक्सटेंशन विंडोज पर चले, तो यह आमतौर पर MVSC के साथ अनुपालन होता है, जो सीमित है C89)। मुझे नहीं पता कि यह कड़ाई से आवश्यक है।
detly

1
अभिव्यक्ति का (complex float) { r, i }उपयोग संख्या के अलग-अलग हिस्सों को और स्वतंत्र रूप से सेट करने के लिए किया जा सकता है (वास्तविक भाग को INF होने की अनुमति देता है जबकि काल्पनिक भाग NAN है, उदाहरण के लिए)। यह GCC- विशिष्ट कीवर्ड से बचा जाता है, हालांकि मुझे यकीन नहीं है कि यह वास्तव में पोर्टेबल है।
क्लेन्ग

2
ध्यान दें कि कॉम्प्लेक्स सपोर्ट C99 में वैकल्पिक है: कंपाइलर्स में यह परिभाषित नहीं होता है कि क्या वे परिभाषित करते हैं __STDC_NO_COMPLEX__। हालांकि व्यवहार में, इसे प्रमुख संकलकों पर लागू किया जाता है।
सिरो सेंटिल्ली 郝海东 i i i 法轮功 '17

1
जैसन, N1256 ड्राफ्ट के पेज 182 को खोलें- std.org/jtc1/sc22/wg14/www/docs/n1256.pdf#page=182 "7.3 कॉम्प्लेक्स अंकगणित < Complex.s >"। इस तरह के कीवर्ड को संभवतः मौजूदा सी (C90) प्रोग्राम्स को तोड़ने के लिए C99 में चुना गया था जो हाथ से जटिल हो जाते हैं। यदि <Complex.h> शामिल है, तो complexइसे मैक्रो के रूप में परिभाषित किया जाएगा , जिसका विस्तार किया जाएगा _Complex। आपको डेरेक एम। जोन्स की "द न्यू सी स्टैंडर्ड: एन इकोनॉमिक एंड कल्चरल कमेंट्री" (2008) पृष्ठ 500 "जटिल प्रकार" के लोग .ece.cornell.edu
land/

9

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));
}

4

सुविधा के लिए, किसी 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;
}

2

नकारात्मक द्विघात जड़ों की गणना की आवश्यकता से, गणित में जटिल संख्याओं की धारणा शुरू की गई थी। जटिल संख्या की अवधारणा विभिन्न इंजीनियरिंग क्षेत्रों द्वारा ली गई थी।

आज कि जटिल संख्याएँ व्यापक रूप से उन्नत इंजीनियरिंग डोमेन जैसे कि भौतिकी, इलेक्ट्रॉनिक्स, यांत्रिकी, खगोल विज्ञान, आदि में उपयोग की जाती हैं ...

नकारात्मक वर्ग मूल उदाहरण का वास्तविक और काल्पनिक भाग:

#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;
}

-1

एक जटिल-मूल्यवान अभिव्यक्ति का वास्तविक हिस्सा निकालने के zलिए, संकेतन का उपयोग करें __real__ z। इसी तरह, __imag__पर विशेषता का उपयोग करेंz काल्पनिक भाग को निकालने के लिए ।

उदाहरण के लिए;

__complex__ float z;
float r;
float i;
r = __real__ z;
i = __imag__ z;

r, कॉम्प्लेक्स नंबर "z" का वास्तविक हिस्सा है, i, कॉम्प्लेक्स नंबर "z" का काल्पनिक हिस्सा है


2
ये जीसीसी-विशिष्ट एक्सटेंशन हैं। एक अन्य उत्तर ने पहले ही उनका उल्लेख किया, और स्वीकृत उत्तर पहले से ही मानक सी में यह कैसे करना है
कीथ थॉम्पसन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.