"Complex Numbers"已经在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是它的超集。实际语法如下:

#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是什么意思。

C99 添加了对复数的本机支持,因此现在它们与普通浮点数或整数一样易于处理。不再有丑陋的结构!大概通过对数字的浮点表示进行技巧,_Complex_I和等效的I宏有一个值,当乘以实数时,会产生许多类型double complexfloat complex(complex是一个新的类型修饰符关键字,也在 C99 中引入)。因此,有了这个新的便利功能,您可以像

#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 + %fn", 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;
}

最新更新