summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaweł Redman <pawel.redman@gmail.com>2018-09-25 23:55:45 +0200
committerPaweł Redman <pawel.redman@gmail.com>2018-09-25 23:55:45 +0200
commit599bbfd06e195a3eaed1069f2ed18fb3610198c4 (patch)
tree7f79f3cd7e9a28981f1393c88c41887db53e168e
parent4d84f6aabdb5b962a990486b588fee3d1919adde (diff)
Add a divide-less version of mastur.
-rw-r--r--Makefile1
-rw-r--r--src/main.c4
-rw-r--r--src/mastur2.c19
3 files changed, 23 insertions, 1 deletions
diff --git a/Makefile b/Makefile
index f069ef2..8d7bd44 100644
--- a/Makefile
+++ b/Makefile
@@ -16,6 +16,7 @@ SRC := src/bigtab.c \
src/new32v2.c \
src/new32v3.c \
src/mastur.c \
+ src/mastur2.c \
src/null.c \
src/ref.c
diff --git a/src/main.c b/src/main.c
index 6651ff3..4f7ba7f 100644
--- a/src/main.c
+++ b/src/main.c
@@ -22,6 +22,7 @@ int new32(int i, int x, int y);
int new32v2(int i, int x, int y);
int new32v3(int i, int x, int y);
int mastur(int i, int x, int y);
+int mastur2(int i, int x, int y);
void bigtab_init(void);
int bigtab(int i, int x, int y);
@@ -42,7 +43,8 @@ static struct solfunc solfuncs[ ] = {
{"new32", new32},
{"new32v2", new32v2},
{"new32v3", new32v3},
- {"mastur", mastur}
+ {"mastur", mastur},
+ {"mastur2", mastur2}
};
#define PASSES 5
diff --git a/src/mastur2.c b/src/mastur2.c
new file mode 100644
index 0000000..1be6d1d
--- /dev/null
+++ b/src/mastur2.c
@@ -0,0 +1,19 @@
+static const unsigned int divtab[244] = {
+ [1] = 0xffff + 1l,
+ [3] = 0x5555 + 1l,
+ [9] = 0x1c71 + 1l,
+ [27] = 0x097b + 1l,
+ [81] = 0x0329 + 1l,
+ [243] = 0x010d + 1l
+};
+
+#define FASTDIV(n, d) (((n) * divtab[d]) >> 16)
+#define FASTMOD(n, d) ((n) - (d) * FASTDIV((n), (d)))
+
+static const int A[] = {0, 1, -1};
+static const int C[][3] = {{1, 1, -2}, {1, 1, -2}, {-2, 1, 1}};
+
+int mastur2(const int i, const int x, const int y)
+{
+ return i + A[x] * C[x][FASTMOD(FASTDIV(i, y), 3)] * y;
+}