diff options
Diffstat (limited to 'zahl-inlines.h')
| -rw-r--r-- | zahl-inlines.h | 69 |
1 files changed, 41 insertions, 28 deletions
diff --git a/zahl-inlines.h b/zahl-inlines.h index 1f04a05..09e09a6 100644 --- a/zahl-inlines.h +++ b/zahl-inlines.h @@ -1,17 +1,24 @@ /* See LICENSE file for copyright and license details. */ ZAHL_INLINE void zinit(z_t a) { a->alloced = 0; a->chars = 0; } -ZAHL_INLINE int zeven(z_t a) { return !a->sign || !(a->chars[0] & 1); } +ZAHL_INLINE int zeven(z_t a) { return !a->sign || (~a->chars[0] & 1); } ZAHL_INLINE int zodd(z_t a) { return a->sign && (a->chars[0] & 1); } -ZAHL_INLINE int zeven_nonzero(z_t a) { return !(a->chars[0] & 1); } +ZAHL_INLINE int zeven_nonzero(z_t a) { return (~a->chars[0] & 1); } ZAHL_INLINE int zodd_nonzero(z_t a) { return (a->chars[0] & 1); } ZAHL_INLINE int zzero(z_t a) { return !a->sign; } ZAHL_INLINE int zsignum(z_t a) { return a->sign; } -ZAHL_INLINE void zabs(z_t a, z_t b) { ZAHL_SET(a, b); a->sign = !!a->sign; } ZAHL_INLINE void zneg(z_t a, z_t b) { ZAHL_SET(a, b); a->sign = -a->sign; } +#if 1 && (-1 & 1) /* In the future, tuning will select the fastest implementation. */ +ZAHL_INLINE void zabs(z_t a, z_t b) { ZAHL_SET(a, b); a->sign &= 1; } +#elif 1 +ZAHL_INLINE void zabs(z_t a, z_t b) { ZAHL_SET(a, b); if (ZAHL_LIKELY(a->sign < 0)) a->sign = 1; } +#else +ZAHL_INLINE void zabs(z_t a, z_t b) { ZAHL_SET(a, b); a->sign = !!a->sign; } +#endif + -ZAHL_INLINE ZAHL_O3 void +ZAHL_INLINE void zswap(z_t a, z_t b) { /* Almost three times faster than the naïve method. */ @@ -23,22 +30,24 @@ zswap(z_t a, z_t b) } -ZAHL_INLINE ZAHL_O3 void +ZAHL_INLINE void zseti(z_t a, int64_t b) { if (ZAHL_UNLIKELY(b >= 0)) { zsetu(a, (uint64_t)b); - } else { - zsetu(a, (uint64_t)-b); - ZAHL_SET_SIGNUM(a, -1); + return; } + ZAHL_ENSURE_SIZE(a, 1); + ZAHL_SET_SIGNUM(a, -1); + a->chars[0] = (zahl_char_t)-b; + a->used = 1; } -ZAHL_INLINE ZAHL_O3 void +ZAHL_INLINE void zsetu(z_t a, uint64_t b) { - if (!b) { + if (ZAHL_UNLIKELY(!b)) { ZAHL_SET_SIGNUM(a, 0); return; } @@ -49,7 +58,7 @@ zsetu(z_t a, uint64_t b) } -ZAHL_INLINE ZAHL_O3 size_t +ZAHL_INLINE size_t zlsb(z_t a) { size_t i = 0; @@ -62,7 +71,7 @@ zlsb(z_t a) } -ZAHL_INLINE ZAHL_O3 size_t +ZAHL_INLINE size_t zbits(z_t a) { size_t rc; @@ -75,7 +84,7 @@ zbits(z_t a) } -ZAHL_INLINE ZAHL_O3 int +ZAHL_INLINE int zcmpmag(z_t a, z_t b) { size_t i, j; @@ -103,7 +112,7 @@ zcmpmag(z_t a, z_t b) } -ZAHL_INLINE ZAHL_O3 int +ZAHL_INLINE int zcmp(z_t a, z_t b) { if (zsignum(a) != zsignum(b)) @@ -112,23 +121,23 @@ zcmp(z_t a, z_t b) } -ZAHL_INLINE ZAHL_O3 int +ZAHL_INLINE int zcmpu(z_t a, uint64_t b) { - extern z_t libzahl_tmp_cmp; if (ZAHL_UNLIKELY(!b)) return zsignum(a); if (ZAHL_UNLIKELY(zsignum(a) <= 0)) return -1; - libzahl_tmp_cmp->chars[0] = b; - return zcmpmag(a, libzahl_tmp_cmp); + while (!a->chars[a->used - 1]) a->used--; /* TODO should not be necessary */ + if (a->used > 1) + return +1; + return a->chars[0] < b ? -1 : a->chars[0] > b; } -ZAHL_INLINE ZAHL_O3 int +ZAHL_INLINE int zcmpi(z_t a, int64_t b) { - extern z_t libzahl_tmp_cmp; if (ZAHL_UNLIKELY(!b)) return zsignum(a); if (ZAHL_UNLIKELY(zzero(a))) @@ -136,18 +145,22 @@ zcmpi(z_t a, int64_t b) if (ZAHL_LIKELY(b < 0)) { if (zsignum(a) > 0) return +1; - libzahl_tmp_cmp->chars[0] = (zahl_char_t)-b; - return -zcmpmag(a, libzahl_tmp_cmp); + while (!a->chars[a->used - 1]) a->used--; /* TODO should not be necessary */ + if (a->used > 1) + return -1; + return a->chars[0] > (zahl_char_t)-b ? -1 : a->chars[0] < (zahl_char_t)-b; } else { if (zsignum(a) < 0) return -1; - libzahl_tmp_cmp->chars[0] = (zahl_char_t)b; - return +zcmpmag(a, libzahl_tmp_cmp); + while (!a->chars[a->used - 1]) a->used--; /* TODO should not be necessary */ + if (a->used > 1) + return +1; + return a->chars[0] < (zahl_char_t)b ? -1 : a->chars[0] > (zahl_char_t)b; } } -ZAHL_INLINE ZAHL_O3 void +ZAHL_INLINE void zbset(z_t a, z_t b, size_t bit, int action) { if (ZAHL_UNLIKELY(a != b)) @@ -185,7 +198,7 @@ fallback: } -ZAHL_INLINE ZAHL_O3 int +ZAHL_O3 ZAHL_INLINE int zbtest(z_t a, size_t bit) { size_t chars; @@ -201,7 +214,7 @@ zbtest(z_t a, size_t bit) } -ZAHL_INLINE ZAHL_O3 void +ZAHL_O3 ZAHL_INLINE void zsplit(z_t high, z_t low, z_t a, size_t delim) { if (ZAHL_UNLIKELY(high == a)) { @@ -214,7 +227,7 @@ zsplit(z_t high, z_t low, z_t a, size_t delim) } -ZAHL_INLINE ZAHL_O3 size_t +ZAHL_O2 ZAHL_INLINE size_t zsave(z_t a, void *buffer) { if (ZAHL_LIKELY(buffer)) { |
