我在一本关于CUDA的书中的Julia Set示例中找到了这个结构代码。我是一个新手C程序员,无法理解它在做什么,也没有找到正确的东西在网上阅读清除它。这是结构:
struct cuComplex {
float r;
float i;
cuComplex( float a, float b ) : r(a), i(b) {}
float magnitude2( void ) { return r * r + i * i; }
cuComplex operator*(const cuComplex& a) {
return cuComplex(r*a.r - i*a.i, i*a.r + r*a.i);
}
cuComplex operator+(const cuComplex& a) {
return cuComplex(r+a.r, i+a.i);
}
};
它的名字非常简单:
cuComplex c(-0.8, 0.156);
cuComplex a(jx, jy);
int i = 0;
for (i=0; i<200; i++) {
a = a * a + c;
if (a.magnitude2() > 1000)
return 0;
}
return 1;
那么,代码做了什么?定义了一些结构类型'cuComplex',给出了数字的实部和虚部。 (-0.8&amp; 0.156)返回什么? (或者放在结构中?)我如何通过结构中运算符的逻辑来理解实际计算和保存的内容?
我认为它可能会将递归调用回到结构
float magnitude2 (void) { return return r * r + i * i; }
可能为r调用'*'运算符,对i再调用,然后这两个运算的结果调用'+'运算符?这是正确的,每一步都会返回什么?
简直困惑。
谢谢!
答案 0 :(得分:1)
就像你说的那样,cuComplex为一个数字的实数(r)和虚数(i)保持两个值。 构造函数只是将值赋给r和i。
*运算符正在处理cuComplex数字。只有在将两个cuComplex等值相乘时,才会调用乘法和加法运算符。
它们只是为了简化您的代码。没有操作员,您必须自己进行添加操作:
cuComplex c(-0.8, 0.156);
cuComplex a(jx, jy);
// Add, both operations are equivalent.
cuComplex result1 = cuComplex(c.r + a.r, c.i + a.i);
cuComplex result2 = c + a;
代码
cuComplex c(-0.8, 0.156); // Create cuComplex instance called c
cuComplex a(jx, jy); // Create cuComplex instance called a
int i = 0;
for (i=0; i<200; i++) {
a = a * a + c; // Use the * and + operator of cuComplex
if (a.magnitude2() > 1000)
return 0;
}
return 1;
我认为它可能正在做 递归调用回到结构
float magnitude2 (void) { return return r * r + i * i; }
不是因为r和我是浮动的。对于cuComplex而不是float
,*和+运算符重载答案 1 :(得分:1)
r
和i
是声明为float
的结构的成员。 magnitude2
函数中的表达式只使用存储在这些成员中的值进行标准浮点运算。
当运算符*
和+
应用于结构类型的变量时,例如在行a = a * a + c
中,将使用结构中定义的运算符函数。
答案 2 :(得分:1)
它是复数的C ++实现,提供了一种返回加法和乘法的幅度和运算符重载的方法。真实的(r
)和虚构的(i
)部分是分开存储的。
a * a + c
调用重载的方法:(a.operator*(a)).operator+(c)
看起来你很难掌握甚至C语法(return r * r + i * i;
返回r
次r
加i
次i
},所以我建议你阅读初学者对C / C ++的介绍,然后介绍复杂的数字,然后阅读C ++中的运算符重载。
答案 3 :(得分:1)
这不是一个简单的结构,而是一个类(它基本上是一个带有函数的结构),而且是C ++。
cuComplex c(-0.8, 0.156);
在这里,他创建了这个类的一个实例,并通过调用构造函数(初始化类的实例字段的特殊函数)来设置2个值。
这可能没有足够的意义所以我建议你学习一本C ++书。如果您已经了解一些编程,那么Accelerated C ++是一个不错的选择。
答案 4 :(得分:1)
乘法运算符只是取参数a的实部和虚部,并将这些部分与调用运算符的对象的实部和虚部相加,并返回结果的新复数对象。我添加了 this 指针来澄清:
cuComplex operator*(const cuComplex& a) {
// first constructor argument is the real part, second is the imaginary part
return cuComplex(this->r*a.r - this->i*a.i, this->i*a.r + this->r*a.i);
}
添加运算符也是如此。再次创建并返回cuComplex类型的新对象的副本。这次它的实部和虚部是 this 对象和参数的各个字段的总和。
cuComplex运算符+(const cuComplex&amp; a){ return cuComplex(this-&gt; r + a.r,this-&gt; i + a.i); }
对于循环,似乎虚数 a 与自身相乘(导致在Re-Im平面中旋转,并且一个恒定的虚数 c 是在每次迭代中添加,直到结果的幅度(长度)超过某个阈值。
请注意,operator *和operator +以及函数magnitude2()都是结构cuComplex的成员,因此 this 指针可用。
希望有所帮助。
答案 5 :(得分:0)
您应该将此问题标记为C++
,而不是C
(即使您有struct
,此问题也有一个构造函数,并重新定义了典型的面向对象概念的运算符)。
此结构定义复数,允许相乘(通过operator*
),添加它们(通过operator+
)并获取其模块(通过magnitude2
)。
在beininning;你有一个常数复数c
和a
,另一个复数不是常数,用户可能通过坐标jx
和{{1 }}。在循环的每次迭代中,jy
自身被多重化,并且a
被添加到此结果中。
如果某时c
的模块大于a
,则循环结束。我想这是一个测试程序,用于查看1000
模块如何根据用户给出的初始条件增长。
答案 6 :(得分:0)
如果您熟悉类的概念,请将“struct”替换为“class”,这样可以更容易理解。
“class”包含两个变量r和i,一个带有两个float args的构造函数,一个乘法运算符,一个要添加的运算符,以及一个计算幅度的函数。
答案 7 :(得分:0)
在C ++中,只需使用std::complex<float>
。