]> git.mar77i.info Git - bigintmandel/commitdiff
use gmp big ints rather than qreal
authormar77i <mar77i@protonmail.ch>
Mon, 1 Apr 2024 09:33:35 +0000 (11:33 +0200)
committermar77i <mar77i@protonmail.ch>
Mon, 1 Apr 2024 11:48:38 +0000 (13:48 +0200)
CMakeLists.txt
bigintwidget.cpp
mandel.cpp
mandel.h

index 243407b58364054a5a3602171e39332597747672..8f38274f0cddb22124cd9db2070d9d7e5e90aaca 100644 (file)
@@ -48,6 +48,7 @@ target_link_libraries(
     PRIVATE
     Qt${QT_VERSION_MAJOR}::Widgets
     Qt${QT_VERSION_MAJOR}::Concurrent
+    gmp
 )
 
 # Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1.
index c965e0fc6445be5251af02452d7b0aebf4e86a35..88a388943d8fb8edc1e64e621e895e7ea75fe3e2 100644 (file)
@@ -10,7 +10,7 @@
 BigintWidget::BigintWidget(QWidget *parent)
 :   QWidget(parent),
     fw(new QFutureWatcher<MandelResultCell>(this)),
-    meta(1024, QSize(1800, 1000)),
+    meta(8192, QSize(1800, 1000)),
     img_label(new QLabel(this)),
     img_dirty(true)
 {
index e633fb0aa6b1cdb3f46957743fc2bded75719be9..795b4e479b68728d354458c67c7735bb62a6af96 100644 (file)
@@ -1,12 +1,18 @@
 
 // mandel.cpp
 
+#include <QDebug>
+
 #include "colors.h"
 #include "mandel.h"
 
+MpzPoint::MpzPoint() : x(), y() {}
+MpzPoint::MpzPoint(mpz_class x, mpz_class y) : x(x), y(y) {}
+MpzPoint::MpzPoint(const MpzPoint &other) : x(other.x), y(other.y) {}
+
 MandelResultCell::MandelResultCell() {}
 
-MandelResultCell::MandelResultCell(size_t iter, QPointF rpos)
+MandelResultCell::MandelResultCell(size_t iter, MpzPoint rpos)
 :   iter(iter), rpos(rpos) {}
 
 static inline void incrpos(QPoint &pos, const int width) {
@@ -17,19 +23,28 @@ static inline void incrpos(QPoint &pos, const int width) {
     }
 }
 
+static inline mpz_class get_one(const QSize size) {
+    int one = std::min(size.width() / 3, size.height() / 3) / 2;
+    one--;
+    one |= one >>  1;
+    one |= one >>  2;
+    one |= one >>  4;
+    one |= one >>  8;
+    one |= one >> 16;
+    return mpz_class(one + 1);
+}
+
 MandelMeta::MandelMeta(size_t max_iter, const QSize size)
 :   max_iter(max_iter),
     img(size, QImage::Format_RGB888),
     cells(size.width() * size.height(), MandelCell(this)),
-    center_f(qreal(-3) / 4, 0),
-    one(1),
-    four(4),
-    scale(std::max(qreal(3) / size.width(), qreal(3) / size.height()))
+    one(::get_one(size))
 {
     QVector<MandelCell>::iterator i;
     QPointF c(size.width() / 2., size.height() / 2.);
     QPoint pos;
 
+    center_f = MpzPoint(one * -3 / 4, 0);
     for (i = cells.begin(); i != cells.end(); incrpos(pos, size.width()), i++) {
         i->set_meta(this);
         i->set_pos(pos);
@@ -38,8 +53,9 @@ MandelMeta::MandelMeta(size_t max_iter, const QSize size)
 
 void MandelMeta::zoom2x(QPoint pos) {
     QVector<MandelCell>::iterator i;
-    center_f = cells[img.width() * pos.y() + pos.x()].get_rpos0();
-    scale /= 2;
+    MpzPoint p = cells[img.width() * pos.y() + pos.x()].get_rpos0();
+    center_f = MpzPoint(p.get_x() * 8, p.get_y() * 8);
+    one *= 8;
     img.fill(Qt::GlobalColor::black);
     for (i = cells.begin(); i != cells.end(); i++)
         i->reset_iter_and_rpos();
@@ -59,10 +75,10 @@ MandelResultCell MandelMeta::iterate(const MandelCell &cell) {
 }
 
 void MandelCell::reset_rpos0() {
-    QPointF center_f = meta->get_center_f();
-    rpos0 = QPointF(
-        center_f.x() + (pos.x() - meta->get_width() / 2.) * meta->get_scale(),
-        center_f.y() + (pos.y() - meta->get_height() / 2.) * meta->get_scale()
+    MpzPoint center_f = meta->get_center_f();
+    rpos0 = MpzPoint(
+        center_f.get_x() + (pos.x() - meta->get_width() / 2.),
+        center_f.get_y() + (pos.y() - meta->get_height() / 2.)
     );
 }
 
@@ -72,7 +88,7 @@ MandelCell::MandelCell(const MandelCell &cell)
 :   meta(cell.meta), pos(cell.pos), iter(cell.iter),
     rpos(cell.rpos), rpos0(cell.rpos0) {}
 
-QPoint MandelCell::update_result(size_t iter, const QPointF &rpos) {
+QPoint MandelCell::update_result(size_t iter, const MpzPoint &rpos) {
     this->iter = iter;
     this->rpos = rpos;
     return pos;
@@ -80,7 +96,7 @@ QPoint MandelCell::update_result(size_t iter, const QPointF &rpos) {
 
 void MandelCell::reset_iter_and_rpos() {
     iter = 0;
-    rpos = QPointF();
+    rpos = MpzPoint();
     reset_rpos0();
 }
 
@@ -94,15 +110,18 @@ void MandelCell::set_pos(QPoint pos) {
 }
 
 MandelResultCell MandelCell::iterate() const {
+    MpzPoint rpos = this->rpos, sq;
+    mpz_class one = meta->get_one(), four = one * one * 4;
+    mpz_class sqx, sqy;
     size_t iter = this->iter;
-    QPointF rpos = this->rpos, sq;
-    for (; iter < this->meta->get_max_iter(); iter++) {
-        sq = QPointF(rpos.x() * rpos.x(), rpos.y() * rpos.y());
-        if (sq.x() + sq.y() > meta->get_four())
+    for (; iter < meta->get_max_iter(); iter++) {
+        sqx = rpos.get_x() * rpos.get_x();
+        sqy = rpos.get_y() * rpos.get_y();
+        if (sqx + sqy > four)
             break;
-        rpos = QPointF(
-            sq.x() - sq.y() + rpos0.x(),
-            2 * rpos.x() * rpos.y() + rpos0.y()
+        rpos = MpzPoint(
+            (sqx - sqy) / one + rpos0.get_x(),
+            rpos.get_x() * rpos.get_y() * 2 / one + rpos0.get_y()
         );
     }
     return MandelResultCell(iter, rpos);
index 487dd0b728486e81bd67224c0a7f36e9c84bf714..99ff14cccf767d7cdad74b56ce99b9ef8b7803bf 100644 (file)
--- a/mandel.h
+++ b/mandel.h
@@ -7,25 +7,36 @@
 #include <QPixmap>
 #include <QPoint>
 #include <QVector>
+#include <gmpxx.h>
 
 class MandelCell;
 
+class MpzPoint {
+    mpz_class x, y;
+public:
+    MpzPoint();
+    MpzPoint(mpz_class x, mpz_class y);
+    MpzPoint(const MpzPoint &other);
+    const mpz_class get_x() const { return x; }
+    const mpz_class get_y() const { return y; }
+};
+
 class MandelResultCell {
     friend class MandelMeta;
 
     size_t iter;
-    QPointF rpos;
+    MpzPoint rpos;
 public:
     MandelResultCell();
-    MandelResultCell(size_t iter, QPointF rpos);
+    MandelResultCell(size_t iter, MpzPoint rpos);
 };
 
 class MandelMeta {
     size_t max_iter;
     QImage img;
     QVector<MandelCell> cells;
-    QPointF center_f;
-    qreal one, four, scale;
+    MpzPoint center_f;
+    mpz_class one;
 
 public:
     MandelMeta(size_t max_iter, QSize size);
@@ -35,9 +46,8 @@ public:
     const int get_height() const { return img.height(); }
     const QSize get_size() const { return img.size(); }
     const QVector<MandelCell> get_cells() const { return cells; }
-    const QPointF get_center_f() const { return center_f; }
-    const qreal get_four() const { return four; }
-    const qreal get_scale() const { return scale; }
+    const MpzPoint get_center_f() const { return center_f; }
+    const mpz_class get_one() const { return one; }
 
     void zoom2x(QPoint pos);
     void finished_cell(int num, const MandelResultCell &cell);
@@ -48,7 +58,7 @@ class MandelCell {
     MandelMeta *meta;
     QPoint pos;
     size_t iter;
-    QPointF rpos, rpos0;
+    MpzPoint rpos, rpos0;
 
 protected:
     void reset_rpos0();
@@ -57,9 +67,9 @@ public:
     MandelCell(MandelMeta *meta);
     MandelCell(const MandelCell &cell);
     inline const size_t get_iter() const { return iter; }
-    inline const QPointF get_rpos0() const { return rpos0; }
+    inline const MpzPoint get_rpos0() const { return rpos0; }
 
-    QPoint update_result(size_t iter, const QPointF &rpos);
+    QPoint update_result(size_t iter, const MpzPoint &rpos);
     void reset_iter_and_rpos();
     void set_meta(MandelMeta *meta);
     void set_pos(const QPoint pos);