[英]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 complex
或float 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解释 。
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.