对于以下代码,
- Objective-C如何知道在复数中添加“i”?当我在Complex.m文件中将“real”和“imaginary”定义为double值时,我认为Xcode只知道“real”和“imaginary”是双值。
- 如果我在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;
}
答案 0 :(得分:12)
复杂数字类型在C99中定义,Objective-C的现代版本是其中的超集。 The actual syntax is like:
#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
后缀为extension coming from 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
是一个“double”,因此是一个真实数字。 C标准建议,当在实数和虚数之间进行转换时,您将得到零(C99§G.4.2/ 1)。因此,你写的有效地是myComplex.imaginary = 0.0;
。
- 如果我添加任何其他字母,程序将无法运行,为什么会这样?
实际上你可以写7.0if
之类的东西。同样,这是一个C-thing,Objective-C已经适应了。您可以添加f
将十进制数字从默认类型“double”变为“float”,GCC会添加一项额外功能,您可以添加i
来转换实数到一个虚数。像7.0x
这样的其他东西会导致编译器停止,因为它不知道x
的含义。
答案 1 :(得分:7)
C99添加了对复数的本机支持,因此现在它们像普通的浮点数或整数一样容易处理。没有更丑陋的结构!假设通过使用数字的浮点表示来做技巧,_Complex_I
和等效的I
宏具有一个值,当乘以实数时,会产生多个类型{{1} }或double complex
(float complex
是一个新的类型修饰符关键字,也在C99中引入)。因此,使用这种新的便利功能,您可以像在
complex
请同时查看the GNU explanation。
#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));
后缀是C99语言的GNU扩展,因此它是非标准的。然而,Xcode(GCC和Clang)使用的两个编译器都实现了这个扩展。
(旁注:Xcode对此知道没有。请不要将IDE与编译器混淆.Xcode本身不会执行编译 - 它背后的编译器会这样做。)
答案 2 :(得分: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
感谢您的耐心等待)
答案 3 :(得分:1)
类复杂实现中存在两个严重错误 - 复数乘以绝对错误的方式进行划分!简单地乘以或除以两个复数的实部和虚部是绝对不够的。在这种情况下你必须使用乘法和除法公式,我认为谷歌包含很多关于它的条目。现在它是错误的代码,必须重写。
对于乘法,它必须是这样的
-(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;
}