aboutsummaryrefslogtreecommitdiffstats
path: root/src/zpow.c
diff options
context:
space:
mode:
authorMattias Andrée <maandree@kth.se>2016-03-03 10:53:26 +0100
committerMattias Andrée <maandree@kth.se>2016-03-03 10:53:26 +0100
commit0e905d00aceaa79849c25d359d7b7a6ee79175d7 (patch)
tree9e3a4da2fff064c1690d8ac00483a1532d529102 /src/zpow.c
parentAdd new functions: zpowu and zmodpowu (diff)
downloadlibzahl-0e905d00aceaa79849c25d359d7b7a6ee79175d7.tar.gz
libzahl-0e905d00aceaa79849c25d359d7b7a6ee79175d7.tar.bz2
libzahl-0e905d00aceaa79849c25d359d7b7a6ee79175d7.tar.xz
Optimise zpow and zmodpow
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat (limited to 'src/zpow.c')
-rw-r--r--src/zpow.c15
1 files changed, 10 insertions, 5 deletions
diff --git a/src/zpow.c b/src/zpow.c
index bc071f8..c359ac3 100644
--- a/src/zpow.c
+++ b/src/zpow.c
@@ -10,7 +10,8 @@
void
zpow(z_t a, z_t b, z_t c)
{
- size_t i, n;
+ size_t i, j, n, bits;
+ zahl_char_t x;
if (zsignum(c) <= 0) {
if (zzero(c)) {
@@ -31,15 +32,19 @@ zpow(z_t a, z_t b, z_t c)
return;
}
- n = zbits(c);
+ bits = zbits(c);
+ n = FLOOR_BITS_TO_CHARS(bits);
zset(tb, b);
zset(tc, c);
zsetu(a, 1);
for (i = 0; i < n; i++) {
- if (zbtest(tc, i))
- zmul(a, a, tb);
- zsqr(tb, tb);
+ x = tc->chars[i];
+ for (j = BITS_PER_CHAR; j--; x >>= 1, j) {
+ if (x & 1)
+ zmul(a, a, tb);
+ zsqr(tb, tb);
+ }
}
}