繁体   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