10

对于以下代码,

-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;
}
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. 同样,这是一个 C 的东西,Objective-C 已经适应了。您可以添加一个f将十进制数从默认类型“double”转换为“float”,并且 GCC 添加了一个额外的功能,您可以添加一个i将实数转换为虚数的功能。其他足够7.0x的东西会导致编译器停止,因为它不知道是什么x意思。

于 2012-10-19T18:21:50.257 回答
7

C99 添加了对复数的原生支持,因此现在它们与普通浮点数或整数一样易于处理。不再有丑陋的结构!据推测,通过对数字的浮点表示进行技巧,the_Complex_I和等效的I宏具有一个值,当乘以实数时,会产生一个数字类型double complexfloat complex(complex是一个新的类型修饰符关键字,也在 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 解释

后缀是 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 的实现有两个严重的错误——复数以绝对错误的方式相乘和除法!仅仅将两个复数的实部和虚部相乘或相除是绝对不够的。在这种情况下你必须使用乘法和除法公式,我认为谷歌包含很多关于它的条目。现在它是错误的代码,必须重写。

对于乘法,它必须是这样的

-(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 回答