aboutsummaryrefslogtreecommitdiff
path: root/src/benchmarks/cfrac/pdivmod.c
diff options
context:
space:
mode:
authorFlorian Fischer <florian.fl.fischer@fau.de>2020-05-06 16:56:32 +0200
committerFlorian Fischer <florian.fl.fischer@fau.de>2020-06-02 11:18:47 +0200
commit8174a918ea3b7cb216bf7ea98cfdc10661b5c37d (patch)
tree0747ec3ccb9f8d7eeccfac35977fc17855ca3bbb /src/benchmarks/cfrac/pdivmod.c
parent8f52e8fc02dd235582f5961941bcd564e9a681cd (diff)
downloadallocbench-8174a918ea3b7cb216bf7ea98cfdc10661b5c37d.tar.gz
allocbench-8174a918ea3b7cb216bf7ea98cfdc10661b5c37d.zip
make the whole project more python idiomatic
* rename src directory to allocbench * make global variable names UPPERCASE * format a lot of code using yapf * use lowercase ld_preload and ld_library_path as Allocator members * name expected Errors 'err' and don't raise a new Exception * disable some pylint messages
Diffstat (limited to 'src/benchmarks/cfrac/pdivmod.c')
-rw-r--r--src/benchmarks/cfrac/pdivmod.c315
1 files changed, 0 insertions, 315 deletions
diff --git a/src/benchmarks/cfrac/pdivmod.c b/src/benchmarks/cfrac/pdivmod.c
deleted file mode 100644
index ce4a24b..0000000
--- a/src/benchmarks/cfrac/pdivmod.c
+++ /dev/null
@@ -1,315 +0,0 @@
-#include "pdefs.h"
-#include "precision.h"
-
-#ifdef DEBUG
-#include <stdio.h>
-#endif
-
-#ifdef ASM_16BIT
-#include "asm16bit.h"
-#endif
-
-/*
- * Divide u (dividend) by v (divisor); If non-null, qp and rp are set to
- * quotient and remainder. The result returned will be *qp, unless qp is
- * NULL, then *rp will be returned if non-null, otherwise pUndef is returned.
- *
- * Produce:
- *
- * q (quotient) = u div v (v != 0)
- * truncation is toward zero
- *
- * r (remainder) = u mod v
- * = u - u div v * v (v != 0)
- * = u (v == 0)
- * ( e.g. u == q*v + r )
- * remainder has same sign and dividend
- *
- * Note: this has opposite convention than the C standard div fuction,
- * but the same convention of the typical C "/" operator
- * It is also inconvienient for the mod function.
- */
-/*
- * This algorithm is taken almost verbatum from Knuth Vol 2.
- * Please note the following trivial(?) array index
- * transformations (since MSD to LSD order is reversed):
- *
- * q[0..m] to Q[0..m] thus q[i] == Q[m-i]
- * r[1..n] R[0..n-1] r[i] == R[n+1-i]
- * u[0..m+n] w[0..m+n] u[i] == w[m+n-i]
- * v[1..n] x[0..n-1] v[i] == x[n-i]
- *
- * let N == n - 1 so that n == N + 1 thus:
- *
- * q[0..m] to Q[0..m] thus q[i] == Q[m-i]
- * r[1..n] R[0..N] r[i] == R[N+2-i]
- * u[0..m+n] w[0..m+N+1] u[i] == w[m+N+1-i]
- * v[1..n] x[0..N] v[i] == x[N+1-i]
- */
-
-/*
- * Note: Be very observent of the usage of uPtr, and vPtr.
- * They are used to point to u, v, w, q or r as necessary.
- */
-precision pdivmod(u, v, qp, rp)
- precision u, v, *qp, *rp;
-{
- register digitPtr uPtr, vPtr, qPtr, LastPtr;
-
- register accumulator temp; /* 0 <= temp < base^2 */
- register digit carry; /* 0 <= carry < 2 */
- register digit hi; /* 0 <= hi < base */
-
- register posit n, m;
- digit d; /* 0 <= d < base */
- digit qd; /* 0 <= qd < base */
-#ifdef DEBUG
- int i;
-#endif
-
- precision q, r, w; /* quotient, remainder, temporary */
-
- n = v->size; /* size of v and r */
-
- (void) pparm(u);
- (void) pparm(v);
- if (u->size < n) {
- q = pUndef;
- r = pUndef;
- pset(&q, pzero);
- pset(&r, u);
- goto done;
- }
-
- m = u->size - n;
-
- uPtr = u->value + m + n;
- vPtr = v->value + n;
-
- q = palloc(m + 1);
- if (q == pUndef) return q;
-
- q->sign = (u->sign != v->sign); /* can generate -0 */
-
- r = palloc(n);
- if (r == pUndef) {
- pdestroy(q);
- return r;
- }
- r->sign = u->sign;
-/*
- * watch out! does this function return: q=floor(a/b) or trunc(a/b)?
- * it's currently the latter, but every mathmaticion I have talked to
- * prefers the former so that a % b returns between 0 to b-1. The
- * problem is that this is slower and disagrees with C common practice.
- */
- qPtr = q->value + m + 1;
-
- if (n == 1) {
- d = *--vPtr; /* d is only digit of v */
- if (d == 0) { /* divide by zero? */
- q = pnew(errorp(PDOMAIN, "pdivmod", "divide by zero"));
- } else { /* single digit divide */
-#ifndef ASM_16BIT
- vPtr = r->value + n;
- hi = 0; /* hi is current remainder */
- do {
- temp = mulBase(hi); /* 0 <= temp <= (base-1)^2 */
- temp += *--uPtr; /* 0 <= temp <= base(base-1) */
- hi = uModDiv(temp, d, --qPtr); /* 0 <= hi < base */
- } while (uPtr > u->value);
- *--vPtr = hi;
-#else
- qPtr -= m + 1;
- *(r->value) = memdivw1(qPtr, u->value, m + 1, d);
-#endif
- }
- } else { /* muti digit divide */
- /*
- * normalize: multiply u and v by d so hi digit of v > b/2
- */
- d = BASE / (*--vPtr+1); /* high digit of v */
-
- w = palloc(n); /* size of v */
- if (w == pUndef) return w;
-
-#ifndef ASM_16BIT
- vPtr = v->value;
- uPtr = w->value; /* very confusing. just a temp */
- LastPtr = vPtr + n;
- hi = 0;
- do { /* single digit multiply */
- temp = uMul(*vPtr++, d); /* 0<= temp <= base(base-1)/2 */
- temp += hi; /* 0 <= temp <= (base^2-1)/2 */
- hi = divBase(temp); /* 0 <= hi < base / 2 */
- *uPtr++ = modBase(temp); /* 0 <= hi < base / 2 */
- } while (vPtr < LastPtr); /* on exit hi == 0 */
-#else
- hi = memmulw1(w->value, v->value, n, d);
-#endif
-
- pset(&v, w);
- pdestroy(w);
-
- w = palloc(m + n + 1);
- if (w == pUndef) return w;
-
-#ifndef ASM_16BIT
- uPtr = u->value;
- vPtr = w->value; /* very confusing. just a temp */
- LastPtr = uPtr + m + n;
- do { /* single digit multiply */
- temp = uMul(*uPtr++, d);
- temp += hi;
- hi = divBase(temp);
- *vPtr++ = modBase(temp);
- } while (uPtr < LastPtr);
- *vPtr = hi; /* note extra digit */
-#else
- hi = memmulw1(w->value, u->value, m + n, d);
- w->value[m + n] = hi;
-#endif
-
- pset(&u, w);
- pdestroy(w);
-
-#ifdef DEBUG
- printf("m = %d n = %d\nd = %d\n", m, n, d);
- printf("norm u = "); pshow(u);
- printf("norm v = "); pshow(v);
-#endif
-
- uPtr = u->value + m + 1; /* current least significant digit */
- do {
- --uPtr;
-#ifdef DEBUG
- printf(" u = ");
- for (i = n; i >= 0; --i) printf("%.*x ", sizeof(digit) * 2, uPtr[i]);
- putchar('\n');
- printf(" v = ");
- for (i = 1; i < 3; i++) printf("%.*x ", sizeof(digit) * 2,
- v->value[n-i]);
- putchar('\n');
-#endif
-#ifndef ASM_16BIT
- vPtr = v->value + n;
- LastPtr = uPtr + n;
- if (*LastPtr == *--vPtr) { /* guess next digit */
- qd = BASE - 1;
- } else {
- temp = mulBase(*LastPtr);
- temp += *--LastPtr; /* 0 <= temp< base^2 */
- temp = uModDiv(temp, *vPtr, &qd);
- --vPtr;
- --LastPtr;
- while (uMul(*vPtr, qd) > mulBase(temp) + *LastPtr) {
- --qd;
- temp += vPtr[1];
- if (temp >= BASE) break; /* if so, vPtr*qd <= temp*base */
- }
- LastPtr += 2;
- }
- /*
- * Single digit Multiply then Subtract
- */
- vPtr = v->value;
- carry = 1; /* noborrow bit */
- hi = 0; /* hi digit of multiply */
- do {
- /* multiply */
- temp = uMul(qd, *vPtr++); /* 0 <= temp <= (base-1)^2 */
- temp += hi; /* 0 <= temp <= base(base-1) */
- hi = divBase(temp);
- temp = modBase(temp);
- /* subtract */
- temp = (BASE-1) - temp; /* 0 <= temp < base */
- temp += *uPtr + carry; /* 0 <= temp < 2*base */
- carry = divBase(temp);
- *uPtr++ = modBase(temp); /* 0 <= carry < 2 */
- } while (uPtr < LastPtr);
- temp = (BASE-1) - hi;
- temp += *uPtr + carry;
- carry = divBase(temp);
- *uPtr = modBase(temp);
- uPtr -= n;
-#else
-#if 0
- carry = !memmulsubw(uPtr, v->value, n, qd); /* 1 if noborrow */
-#endif
- carry = !memdivw(uPtr, v->value, n, &qd); /* 1 if noborrow */
-#endif
-#ifdef DEBUG
- printf(" qhat = %.*x\n", sizeof(digit) * 2, qd);
- printf(" new u = ");
- for (i = n; i >= 0; --i) printf("%.*x ", sizeof(digit) * 2, uPtr[i]);
- putchar('\n');
-#endif
- if (carry == 0) { /* Test remainder, add back */
- vPtr = v->value;
- LastPtr = uPtr + n;
- do {
- temp = *uPtr + *vPtr++;
- temp += carry;
- carry = divBase(temp);
- *uPtr++ = modBase(temp);
- } while (uPtr < LastPtr);
- *uPtr += carry - BASE; /* real strange but works */
- uPtr -= n;
- --qd;
-#ifdef DEBUG
- printf(" decrementing q...adding back\n");
- printf(" fixed u = ");
- for (i = n; i >= 0; --i) printf("%.*x ", sizeof(digit) * 2, uPtr[i]);
- putchar('\n');
- printf(" newq = %.*x\n", sizeof(digit) * 2, qd);
-#endif
- }
- *--qPtr = qd; /* one leading zero possible */
-#ifdef DEBUG
- putchar('\n');
-#endif
- } while (uPtr > u->value);
-
- /*
- * Un-normalize to get remainder
- */
-#ifndef ASM_16BIT
- uPtr = u->value + n; /* skip hi digit (it's zero) */
- vPtr = r->value + n;
- hi = 0; /* hi is current remainder */
- do { /* single digit divide */
- temp = mulBase(hi); /* 0<=temp < base^2-(base-1) */
- temp += *--uPtr; /* 0 <= temp < base^2 */
- hi = uModDiv(temp, d, --vPtr);
- } while (uPtr > u->value); /* carry will be zero */
-#else
- carry = memdivw1(r->value, u->value, n, d); /* always 0 */
-#endif
- pnorm(r); /* remainder may have many leading 0's */
- }
-
- if (m > 0 && qPtr[m] == 0) {
- --(q->size); /* normalize */
- }
- if (q->size == 1 && *qPtr == 0) q->sign = false;
-
-done:
-
- pdestroy(u);
- pdestroy(v);
-
- if (rp == (precision *) -1) {
- if (qp != pNull) pset(qp, q);
- pdestroy(q);
- return presult(r);
- } else if (qp == (precision *) -1) {
- if (rp != pNull) pset(rp, r);
- pdestroy(r);
- return presult(q);
- }
- if (qp != pNull) pset(qp, q);
- if (rp != pNull) pset(rp, r);
- pdestroy(q);
- pdestroy(r);
- return pUndef;
-}