初めてマンデルブロー生成器を作成する場合は、このComplex
型を使用することをお勧めします。時期尚早の最適化は諸悪の根源です。また、マンデルブロのクールさの半分は、わずか数行のコードで驚くべき画像を生成できることです。BigDecimal
その目的のために独自の種類の敗北を実装するのに 2 時間を費やします。
ただし、あなたが言及したとは思わない別のオプションがあります。IEEE 浮動小数点の代わりに、固定小数点演算を使用します。足し算はまったく同じで、掛け算もほぼ同じなので、固定小数点演算はマンデルブロ生成に非常に便利(x * y)
です(x * y) >> MANTISSABITS
。
スポイラー警告!これは、私が数年前に書いた不動点マンデルブロー生成器です。小数点以下 28 ビットを使用します。ツールチェーンが をサポートしている場合int128_t
、またはアセンブリに落としても構わない場合、または長い間乗算を行うことを気にしない場合は、60 ビットの解像度に簡単に置き換えint32_t
て取得できます。int64_t
#include <stdio.h>
#include <stdint.h>
#include "ImageFmtc.h"
/* Represent each component of the complex number
* as a fixed-point value between -4 and +4. There
* are 4 bits before the binary point and 28 bits after. */
typedef int32_t REALFIXED;
typedef int32_t IMAGFIXED;
#define MandelWidth 300
#define MandelHeight 300
unsigned char Image[MandelWidth][MandelHeight];
void mandelbrot(REALFIXED centerx, IMAGFIXED centery, REALFIXED windowsize)
{
int x, y;
unsigned char *image_ptr = &Image[0][0];
for (y = 0; y < MandelHeight; ++y) {
const IMAGFIXED z_imag = (1LL * windowsize * y / MandelHeight) + centery;
for (x = 0; x < MandelWidth; ++x) {
const REALFIXED z_real = (1LL * windowsize * x / MandelWidth) + centerx;
REALFIXED t_real = z_real;
IMAGFIXED t_imag = z_imag;
int iter;
for (iter=0; iter < 255; ++iter) {
long long r2 = (1uLL * t_real * t_real) >> 28;
long long i2 = (1uLL * t_imag * t_imag) >> 28;
long long two_ri = (1uLL * t_real * t_imag) >> 27;
if (r2 + i2 > (4LL << 28))
break;
t_real = (r2 - i2) + z_real;
t_imag = (two_ri) + z_imag;
}
*image_ptr++ = iter & 0xFF;
}
}
return;
}
REALFIXED double2fixed(double x)
{
return (REALFIXED)(x * (1uLL << 28));
}
int main(int argc, char **argv)
{
double cx, cy, scale;
sscanf(argv[1], "%lf", &cx);
sscanf(argv[2], "%lf", &cy);
sscanf(argv[3], "%lf", &scale);
mandelbrot(double2fixed(cx-scale/2), double2fixed(cy-scale/2), double2fixed(scale));
WritePGM5("mandel.pgm", (unsigned char *)Image, MandelWidth, MandelHeight);
return 0;
}
太陽系のサイズについて:数値の解像度が 60 ビットであっても、60 ビットの解像度で設定されたマンデルブロのピクセル精度のレンダリングを実際に計算できるとは限りません。乗算の丸め誤差は、ズームインすると、イメージが予想よりもはるかに速くぼやけてぼやけてしまうことを意味します。誰かが計算したと確信していますが、頭の中でそれを知りません。キーワード「エラー伝播」。