10

次のコードの場合、

-Objective-Cは、複素数に「i」を追加することをどのように知っていますか?Complex.mファイルで「実数」と「虚数」をdouble値として定義したとき、Xcodeは「実数」と「虚数」がdouble値であることだけを知っていると思いました。

-たとえば、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;
}
4

4 に答える 4

12

複素数型はC99で定義されており、Objective-C の最新バージョンはそのスーパーセットです。実際の構文は次のようになります。

#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、「倍精度」であるため、実数です。C 標準では、実数と虚数を変換するときにゼロを取得することを推奨しています (C99 §G.4.2/1)。したがって、事実上、あなたが書いたものはmyComplex.imaginary = 0.0;.

  • 他の文字を追加すると、プログラムが実行されなくなります。なぜですか?

実際には のように書けます7.0if。繰り返しますが、これは Objective-C が適応した C のものです。を追加しfて、10 進数をデフォルト タイプの「double」から「float」に変換することができます。GCC では、 を追加しiて実数を虚数に変換できる機能が追加されています。のような他のサフィックスは、意味7.0xがわからないため、コンパイラを停止させxます。

于 2012-10-19T18:21:50.257 に答える
7

C99 は複素数のネイティブ サポートを追加したため、通常の浮動小数点数や整数と同じくらい簡単に処理できるようになりました。醜い構造体はもう必要ありません。おそらく、数値の浮動小数点表現でトリックを行うことにより、_Complex_Iおよび同等のマクロは、実数で乗算すると、 orI型の数値になる値を持ちます(は、C99 で導入された新しい型修飾子キーワードです)。 . したがって、この新しい便利な機能を使用すると、C で複素数計算を次のように簡単に実行できます。double complexfloat complexcomplex

#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の説明を確認してください。

サフィックスは C99 言語のiGNU 拡張であるため、非標準です。それにもかかわらず、Xcode で使用される両方のコンパイラ (GCC と Clang) は、この拡張機能を実装しています。

(補足: Xcodeはこれについて何も知りません。IDE とコンパイラを混同しないでください。Xcode 自体はコンパイルを実行しません - その背後にあるコンパイラが実行します。)

于 2012-10-19T18:25:03.977 に答える
2

これは、プロジェクトの目的で開発した複素数を操作するためのクラスです。誰かの役に立つかもしれません。これには、標準的な加算、減算、乗算、除算の方法が含まれています。さらに、複素数の法と引数を計算するメソッドがあります。そして最後に、高速フーリエ変換を扱うときに「バタフライ」アルゴリズムに役立つ回転係数 (複素指数) を計算するためのクラス メソッドがあります。

#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

お待ち頂きまして、ありがとうございます )

于 2012-11-08T13:17:40.417 に答える
1

クラス Complex の実装には重大な間違いが 2 つあります。複素数の掛け算と割り算の方法がまったく間違っています。2 つの複素数の実数部と虚数部を単に乗算または除算するだけでは絶対に十分ではありません。その場合、掛け算と割り算の公式を使用する必要があります。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;
}
于 2012-11-07T21:23:36.773 に答える