双精度乘法 C++
Multiplications with doubles c++
我是 C++ 的新手,我想编写其中的 mandelbrot 集以进行一些练习并将速度与 Python 进行比较。我迭代查看复数是否爆炸到无穷大的函数如下所示:
int iterate(double ir, double ii, int iterations){
double sr = 0.0;
double si = 0.0;
unsigned int steps = 0;
while(sr < 2.0 && sr > -2.0 && si < 2.0 && si > -2.0 && steps < iterations){
sr = sr*sr-si*si+ir;
si = si*sr*2 + ii;
steps ++;
}
return steps;
}
我将输出与我的 python 代码进行了比较,发现它更新虚部的行无法正常工作。 *2 不能正常工作。将其加倍而不是使结果为负。例如,当我插入数字 0.2 + 1i 时,它会执行以下操作:
0.2 + 1i,-0.76 - 0.52i,0.5072 + 0.472512i,0.233984 + 1.22112i,-1.23639 - 2.01956i
它应该做的(我从我的 Python 程序中得到的)是:
0.2+ 1i, -0.76 + 1.4i, -1.1823999999999997 - 1.1279999999999997i, 0.3256857599999999 + 3.6674943999999985i
我的猜测是它写入符号而不是将尾数加倍或增加指数。我不能只让它无符号,因为它还必须能够存储负值。你能为这个做什么?感谢您的遮阳篷!
我会这样写你的函数,使用 std::complex
:
template <class T>
std::size_t iterate(std::complex<T> c, std::size_t max_iterations) {
std::complex<T> z = 0;
std::size_t steps = 0;
while (std::norm(z) <= 4 && steps < max_iterations) {
z = z * z + c;
++steps;
}
return steps;
}
然后你可以这样调用你的函数:
using std::complex_literals::operator""i;
std::complex<double> c = 0.2 + 1i; // or c(0.2, 1);
const auto steps = iterate(c, 256);
你应该使用 std::norm(z) <= 4
而不是 std::abs(z) <= 2
is because it's less costly to compute 的原因。
如果在每次迭代后将 z
流式传输到 std::cout
,您可以验证 following program 是否输出了预期的序列:
(0.2,1)(-0.76,1.4)(-1.1824,-1.128)(0.325686,3.66749)
嗯,我知道我来晚了一点,但我认为这是值得的:我在没有图书馆的情况下解决了我的问题。这实际上是一个相当愚蠢的错误:我用新的实数值来计算新的虚数值而不是以前的虚数值。我通过添加一个存储先前实际值的“缓冲区”变量来修复它。我当前的代码是:
int iterate(double r,double i, int max_iterations) {
double ir = 0;
double nir;
double ii = 0;
int steps = 0;
while (ir*ir+ii*ii <= 4 && steps < max_iterations) {
nir = ir*ir-ii*ii+r;
ii = 2*ir*ii + i;
ir = nir;
++steps;
}
return steps;
}
它工作得非常好,而且比库的解决方案快得多。我估计它快了大约 5-10 倍,这就是我决定分享它的原因。如果我在发布版本中编译它,它几乎会立即使用 windows.h header 为我的图形呈现。
我是 C++ 的新手,我想编写其中的 mandelbrot 集以进行一些练习并将速度与 Python 进行比较。我迭代查看复数是否爆炸到无穷大的函数如下所示:
int iterate(double ir, double ii, int iterations){
double sr = 0.0;
double si = 0.0;
unsigned int steps = 0;
while(sr < 2.0 && sr > -2.0 && si < 2.0 && si > -2.0 && steps < iterations){
sr = sr*sr-si*si+ir;
si = si*sr*2 + ii;
steps ++;
}
return steps;
}
我将输出与我的 python 代码进行了比较,发现它更新虚部的行无法正常工作。 *2 不能正常工作。将其加倍而不是使结果为负。例如,当我插入数字 0.2 + 1i 时,它会执行以下操作:
0.2 + 1i,-0.76 - 0.52i,0.5072 + 0.472512i,0.233984 + 1.22112i,-1.23639 - 2.01956i
它应该做的(我从我的 Python 程序中得到的)是:
0.2+ 1i, -0.76 + 1.4i, -1.1823999999999997 - 1.1279999999999997i, 0.3256857599999999 + 3.6674943999999985i
我的猜测是它写入符号而不是将尾数加倍或增加指数。我不能只让它无符号,因为它还必须能够存储负值。你能为这个做什么?感谢您的遮阳篷!
我会这样写你的函数,使用 std::complex
:
template <class T>
std::size_t iterate(std::complex<T> c, std::size_t max_iterations) {
std::complex<T> z = 0;
std::size_t steps = 0;
while (std::norm(z) <= 4 && steps < max_iterations) {
z = z * z + c;
++steps;
}
return steps;
}
然后你可以这样调用你的函数:
using std::complex_literals::operator""i;
std::complex<double> c = 0.2 + 1i; // or c(0.2, 1);
const auto steps = iterate(c, 256);
你应该使用 std::norm(z) <= 4
而不是 std::abs(z) <= 2
is because it's less costly to compute 的原因。
如果在每次迭代后将 z
流式传输到 std::cout
,您可以验证 following program 是否输出了预期的序列:
(0.2,1)(-0.76,1.4)(-1.1824,-1.128)(0.325686,3.66749)
嗯,我知道我来晚了一点,但我认为这是值得的:我在没有图书馆的情况下解决了我的问题。这实际上是一个相当愚蠢的错误:我用新的实数值来计算新的虚数值而不是以前的虚数值。我通过添加一个存储先前实际值的“缓冲区”变量来修复它。我当前的代码是:
int iterate(double r,double i, int max_iterations) {
double ir = 0;
double nir;
double ii = 0;
int steps = 0;
while (ir*ir+ii*ii <= 4 && steps < max_iterations) {
nir = ir*ir-ii*ii+r;
ii = 2*ir*ii + i;
ir = nir;
++steps;
}
return steps;
}
它工作得非常好,而且比库的解决方案快得多。我估计它快了大约 5-10 倍,这就是我决定分享它的原因。如果我在发布版本中编译它,它几乎会立即使用 windows.h header 为我的图形呈现。