簡體   English   中英

在Objective-C中是否已經定義了“復數”?

[英]Are “Complex Numbers” already defined in Objective-C?

對於以下代碼,

-Objective-C如何知道在復數上添加“ i”? 當我在Complex.m文件中將“實數”和“虛數”定義為雙精度值時,我認為Xcode僅會知道“實數”和“虛數”是雙精度值。

-例如,如果我在main.m文件中的復數末尾添加“ i”,則如果將“ myComplex.imaginary = 7;”設置為 變成“ myComplex.imaginary = 7i;” 該行的輸出變為0.00000i,如果我添加任何其他字母,該程序將根本無法運行,這是為什么?

基本上,對我來說,Xcode已經知道“真實”和“虛構”的含義,我所關注的書沒有對此進行詳細說明,因此我有些困惑。

另外,我應該注意,由於我自己無法解決問題,因此未創建以下代碼,這些代碼是從我的圖書論壇的成員中復制的。

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

復數類型在C99中定義,Objective-C的現代版本是C99的超集。 實際語法如下

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

i后綴是來自GCC擴展 Xcode使用的編譯器(clang)具有與GCC兼容的大多數功能,因此您可以編寫3.4i並且沒有錯誤。


對於您的問題,

  • Objective-C如何知道在復數上添加“ i”?

如果您的意思是輸出,那么沒有Objective-C會添加“ i”。 它打印“ i”只是因為您告訴它

-(void) print
{
    NSLog(@"%f + %fi", real, imaginary);
//                 ^
}
  • 如果我打開“ myComplex.imaginary = 7;” 變成“ myComplex.imaginary = 7i;” 該行的輸出變為0.00000i

因為7i是虛數,而myComplex.imaginary是“雙myComplex.imaginary ”,因此是數。 C標准建議在實數和虛數之間轉換時,您將得到零(C99§G.4.2/ 1)。 因此,實際上您編寫的是myComplex.imaginary = 0.0;

  • 如果我添加任何其他字母,該程序將根本無法運行,這是為什么?

實際上,您可以編寫7.0if類的7.0if 同樣,這是Objective-C適應的C事物。 您可以添加f以將十進制數從默認類型“ double”轉換為“ float”,並且GCC添加了一項額外功能,您可以添加i將實數轉換為虛數。 諸如7.0x類的其他滿足條件也會導致編譯器停止運行,因為它不知道x含義。

C99增加了對復數的本機支持,因此現在它們像普通的浮點數或整數一樣容易處理。 不再有丑陋的結構! 大概通過對數字的浮點表示進行技巧, _Complex_I和等效的I宏具有一個值,當與實數相乘時,會導致多個類型為double complexfloat complexcomplex是一個新的類型修飾符關鍵字,也在C99中引入)。 因此,借助這一新的便利功能,您可以像在C語言中一樣輕松地執行復數計算

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

請同時查看GNU解釋

i后綴是C99語言的GNU擴展,因此是非標准的。 盡管如此,Xcode使用的兩個編譯器(GCC和Clang)都實現了此擴展。

(旁注:Xcode 對此一無所知 。請不要將IDE與編譯器混淆。Xcode本身不執行編譯-它背后的編譯器可以執行。)

這是我為項目目的而開發的用於處理復數的類。 可能對某人有用。 它包含標准的加,減,乘和除法。 此外,它還具有計算模數和復數參數的方法。 並且,最后,它具有用於計算轉折因子(復指數)的類方法,該方法對於處理快速傅立葉變換時的“蝴蝶”算法很有用

#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

謝謝你的耐心 )

類復雜實現中有兩個嚴重的錯誤-復數以絕對錯誤的方式相乘和除法! 僅僅將兩個復數的實部和虛部相乘或相除是絕對不夠的。 在這種情況下,您必須使用乘法和除法公式,我認為Google包含很多關於它的條目。 現在,它是錯誤的代碼,必須將其重寫。

對於乘法,它必須是這樣的

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM