diff options
| author | Florian Fischer <florian.fl.fischer@fau.de> | 2020-05-06 16:56:32 +0200 |
|---|---|---|
| committer | Florian Fischer <florian.fl.fischer@fau.de> | 2020-06-02 11:18:47 +0200 |
| commit | 8174a918ea3b7cb216bf7ea98cfdc10661b5c37d (patch) | |
| tree | 0747ec3ccb9f8d7eeccfac35977fc17855ca3bbb /src/benchmarks/cfrac/pdivmod.c | |
| parent | 8f52e8fc02dd235582f5961941bcd564e9a681cd (diff) | |
| download | allocbench-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.c | 315 |
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; -} |
