2012-10-19 13 views
10

Per il seguente codice,I "Numeri complessi" sono già definiti in Objective-C?

-Come fa l'Objective-C sapere di aggiungere una "i" ai numeri complessi? Quando ho definito "reale" e "immaginario" come valori doppi nel file Complex.m, ho pensato che Xcode avrebbe dovuto SOLO sapere che "reale" e "immaginario" sono valori doppi.

-If Aggiungo un "i" alla fine di un numero complesso nel file main.m, ad esempio se giro "myComplex.imaginary = 7;" in "myComplex.imaginary = 7i;" l'output per quella linea diventa 0.00000i, se aggiungo altre lettere, il programma semplicemente non funzionerà, perché è questo?

Fondamentalmente mi sembra che il significato di "reale" e "immaginario" sia già noto a Xcode, il libro che sto seguendo non ha specificato questo quindi sono un po 'confuso.

Inoltre, dovrei notare che non ho creato il codice seguente poiché non sono riuscito a capire da solo il problema, questo codice è stato copiato da un membro del forum dei miei libri.

// Complex.h 

#include <Foundation/Foundation.h> 

@interface Complex : NSObject 
@property double real, imaginary; 
-(void) print; 
-(Complex *) add: (Complex *) complexNum; 
-(Complex *) subtract: (Complex *) complexNum; 
-(Complex *) multiply: (Complex *) complexNum; 
-(Complex *) divide: (Complex *) complexNum; 
@end 

// Complex.m 

#import "Complex.h" 

@implementation Complex 
@synthesize real, imaginary; 

-(void) print 
{ 
    NSLog(@"%f + %fi", real, imaginary); 
} 
-(Complex *) add: (Complex *) complexNum 
{ 
    Complex *result = [[Complex alloc]init]; 
    result.real = real + complexNum.real; 
    result.imaginary = imaginary + complexNum.imaginary; 
    return result; 
} 
-(Complex *) subtract: (Complex *) complexNum 
{ 
    Complex *result = [[Complex alloc]init]; 
    result.real = real - complexNum.real; 
    result.imaginary = imaginary - complexNum.imaginary; 
    return result; 
} 
-(Complex *) multiply: (Complex *) complexNum 
{ 
    Complex *result = [[Complex alloc]init]; 
    result.real = real * complexNum.real; 
    result.imaginary = imaginary * complexNum.imaginary; 
    return result; 
} 
-(Complex *) divide: (Complex *) complexNum 
{ 
    Complex *result = [[Complex alloc]init]; 
    result.real = real/complexNum.real; 
    result.imaginary = imaginary/complexNum.imaginary; 
    return result; 
} 
@end 

// 
// main.m 
// Complex 

#include <Foundation/Foundation.h> 
#import "Complex.h" 

int main(int argc, const char *argv[]) { 

    @autoreleasepool { 
     Complex *myComplex = [[Complex alloc]init]; 
     Complex *totalComplex = [[Complex alloc]init]; 
     Complex *yourComplex = [[Complex alloc]init]; 

     myComplex.real = 5.3; 
     myComplex.imaginary = 7; 
     [myComplex print]; 
     NSLog(@"+"); 

     yourComplex.real = 2.7; 
     yourComplex.imaginary = 4; 
     [yourComplex print]; 
     NSLog(@"="); 

     totalComplex = [myComplex add: yourComplex]; 
     [totalComplex print]; 
    } 
    return 0; 
} 
+5

Oh no! Una domanda non n00b in inglese comprensibile! Cosa è successo a SO? (+1) –

risposta

12

tipi numeri complessi sono definiti in C99, che la versione moderna di Objective-C è un superset di. The actual syntax is like:

#include <complex.h> 

... 

complex double z = 2.7 + 3.4*I; 
complex double w = 4.5 - 1.7*I; 
complex double t = z*w; 
printf("%g + %gi", creal(t), cimag(t)); 

Questo i suffisso è un extension coming from GCC. Il compilatore (clang) usato da Xcode ha la maggior parte delle caratteristiche compatibili con GCC, quindi puoi scrivere 3.4i e non avere errori.


E per le vostre domande,

  • Come si fa a Objective-C sanno per aggiungere una "i" per i numeri complessi?

Se vuoi dire l'uscita, non Objective-C non sa di aggiungere una "i". Esso stampa la "i" solo perché hai detto di

-(void) print 
{ 
    NSLog(@"%f + %fi", real, imaginary); 
//    ^
} 
  • se giro "myComplex.imaginary = 7;" in "myComplex.imaginary = 7i;" l'uscita per quella linea diventa 0.00000i

Poiché 7i è un numero immaginario, e myComplex.imaginary è un "doppio", quindi un numero reale . Lo standard C raccomanda che, durante la conversione tra numeri reali e immaginari, si ottenga zero (C99 §G.4.2/1). Così efficacemente quello che hai scritto è myComplex.imaginary = 0.0;.

  • se aggiungo qualsiasi altra lettera, il programma semplicemente non correre, perché è questo?

In realtà è possibile scrivere le cose come 7.0if. Di nuovo, questa è una cosa C, che Objective-C ha adattato.È possibile aggiungere un f per trasformare un numero decimale dal tipo predefinito "double" a "float" e GCC aggiunge una funzione aggiuntiva che è possibile aggiungere un i per trasformare un numero reale in un numero immaginario. Altro sufficiente come 7.0x causerà l'arresto del compilatore perché non sa cosa significa x.

+0

Haha, era così, a quanto pare non ho potuto raggiungerti;) –

+0

Grazie! Capisco perfettamente e non ho nemmeno notato il "% fi" nel registro NS, al prossimo capitolo. – Ronald

7

C99 ha aggiunto il supporto nativo per numeri complessi, quindi ora sono facili da gestire come numeri in virgola mobile o interi. Niente più brutti progetti! Presumibilmente facendo trucchi con la rappresentazione in virgola mobile dei numeri, la macro _Complex_I e la macro I equivalente hanno un valore che, moltiplicato per un numero reale, restituisce un numero di tipo double complex o float complex (complex è una nuova parola chiave modificatore di tipo, introdotto anche nel C99). Quindi, con questa nuova caratteristica di praticità, è possibile eseguire calcoli complessi numero di C con la stessa facilità

#include <complex.h> 

double complex z1 = 2.0 + 3.0 * I; 
double complex z2 = 1.5 - 2.0 * I; 
double complex prod = z1 * z2; 

printf("Product = %f + %f\n", creal(prod), cimag(prod)); 

Si prega di verificare the GNU explanation su questo così.

Il suffisso i è un'estensione GNU per il linguaggio C99, pertanto non è standard. Tuttavia, entrambi i compilatori utilizzati da Xcode (GCC e Clang) implementano questa estensione.

(. Nota a margine: Xcode sa nulla su questo Si prega di non confondere l'IDE Xcode con il compilatore in sé non esegue la compilazione - i compilatori dietro di esso fanno..)

+0

Grazie, l'equazione nella spiegazione GNU è stata utile. – Ronald

1

Ci sono due errori gravi in classe Implementazione complessa: i numeri complessi vengono moltiplicati e divisi in modo assolutamente sbagliato! Non è assolutamente sufficiente moltiplicare o dividere parti reali e immaginarie di due numeri complessi. In questo caso devi utilizzare moltiplicazioni e formule di divisione, penso che Google contenga molte voci a riguardo. In questo momento è un codice errato e deve essere riscritto.

Per la moltiplicazione deve essere qualcosa di simile

-(Complex *)mul:(Complex *)n 
{ 
    Complex *res = [[Complex alloc]init]; 
    res.re = re * n.re - im * n.im; 
    res.im = re * n.im + im * n.re; 
    return res; 
} 
2

Ecco classe per operare con i numeri complessi che ho sviluppato ai fini del mio progetto. Potrebbe essere utile a qualcuno. Contiene metodi di addizione, sottrazione, moltiplicazione e divisione standard. Inoltre ha un metodo per calcolare il modulo e l'argomento del numero complesso. E, infine, non ha metodo di classe per il calcolo fattore di rotazione (complesso esponente) che è utile per "farfalla" algoritmo quando affare con veloce di Fourier trasformazione

#import <Foundation/Foundation.h> 

@interface Complex : NSObject 
@property double re, im; 
-(Complex *)add :(Complex *) n; 
-(Complex *)sub :(Complex *) n; 
-(Complex *)mul :(Complex *) n; 
-(Complex *)div :(Complex *) n; 
+(Complex *)wkn :(int) k :(int) n; 
-(double)mod; 
-(double)arg; 
@end 

#import "Complex.h" 

@implementation Complex 
@synthesize re, im; 
// Addition of two complex numbers 
-(Complex *)add:(Complex *)n 
{ 
    Complex *res = [[Complex alloc]init]; 
    res.re = re + n.re; 
    res.im = im + n.im; 
    return res; 
} 
// Subtraction of two complex numbers 
-(Complex *)sub:(Complex *)n 
{ 
    Complex *res = [[Complex alloc]init]; 
    res.re = re - n.re; 
    res.im = im - n.im; 
    return res; 
} 
// Multiplication of two complex numbers 
-(Complex *)mul:(Complex *)n 
{ 
    Complex *res = [[Complex alloc]init]; 
    res.re = re * n.re - im * n.im; 
    res.im = re * n.im + im * n.re; 
    return res; 
} 
// Division of two complex numbers 
-(Complex *)div: (Complex *)n 
{ 
    Complex *res = [[Complex alloc]init]; 
    double A = (pow(n.re, 2.0) + pow(n.im, 2.0)); 
    res.re = (re * n.re - im * n.im)/A; 
    res.im = (im * n.re - re * n.im)/A; 
    return res; 
} 
// Modulus of complex number 
-(double)mod 
{ 
    double res = sqrt(pow(re, 2.0) + pow(im, 2.0)); 
    return res; 
} 
// Argument of complex number 
-(double)arg 
{ 
    double res; int quad; 
    if (re == 0 && im > 0) res = M_PI_2; 
    else if (re == 0 && im < 0) res = 3 * M_PI_2; 
    else 
    { 
     if (re > 0 && im >= 0) quad = 1; 
     else if (re < 0 && im >= 0) quad = 2; 
     else if (re < 0 && im < 0) quad = 3; 
     else if (re > 0 && im < 0) quad = 4; 
     double temp = atan(im/re); 
     switch (quad) 
     { 
      case 1: 
       res = temp; 
       break; 
      case 4: 
       res = 2 * M_PI + temp; 
       break; 
      case 2: case 3: 
       res = M_PI + temp; 
       break; 
     } 
    } 
    return res; 
} 
// Turning factor calculation for "butterfly" FFT algorithm 
+(Complex *)wkn:(int)k :(int)n 
{ 
    Complex *res = [[Complex alloc]init]; 
    res.re = cos(2 * M_PI * k/n); 
    res.im = -sin(2 * M_PI * k/n); 
    return res; 
} 

@end 

Grazie per la vostra pazienza)

Problemi correlati