diff options
| author | Florian Fischer <florian.fl.fischer@fau.de> | 2019-08-24 17:57:51 +0200 |
|---|---|---|
| committer | Florian Fischer <florian.fl.fischer@fau.de> | 2019-08-24 17:57:51 +0200 |
| commit | 77ac9ce0a5c55d4f79f8fb8f7daa59ddb53cb507 (patch) | |
| tree | 93d4e30a207265af03394d347bfff76ba677f3ce /src/benchmarks/cfrac/pidiv.c | |
| parent | 971adefadb94e8780b1a73f08ed11d76c2ead8a2 (diff) | |
| download | allocbench-77ac9ce0a5c55d4f79f8fb8f7daa59ddb53cb507.tar.gz allocbench-77ac9ce0a5c55d4f79f8fb8f7daa59ddb53cb507.zip | |
add cfrac benchmark
Diffstat (limited to 'src/benchmarks/cfrac/pidiv.c')
| -rw-r--r-- | src/benchmarks/cfrac/pidiv.c | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/src/benchmarks/cfrac/pidiv.c b/src/benchmarks/cfrac/pidiv.c new file mode 100644 index 0000000..61c09a7 --- /dev/null +++ b/src/benchmarks/cfrac/pidiv.c @@ -0,0 +1,60 @@ +#include "pdefs.h" +#include "precision.h" +#ifdef ASM_16BIT +#include "asm16bit.h" +#endif + +/* + * Single-digit divide + */ +precision pidiv(u, v) + register precision u; + int v; +{ +#ifndef ASM_16BIT + register digitPtr uPtr, qPtr; + register accumulator temp; /* 0 <= temp < base^2 */ +#endif + register digit r, d; /* 0 <= r,d < base */ + register posit m; + register precision q; + + (void) pparm(u); + + if (v < 0) d = (digit) -v; else d = (digit) v; + if (d >= BASE) { + q = pnew(errorp(PDOMAIN, "pidiv", "divisor too big for single digit")); + goto done; + } + if (d == 0) { + q = pnew(errorp(PDOMAIN, "pidiv", "divide by zero")); + goto done; + } + m = u->size; + q = palloc(m); + if (q == pUndef) goto done; + +#ifndef ASM_16BIT + qPtr = q->value + m; + uPtr = u->value + m; + r = 0; /* r is current remainder */ + do { + temp = mulBase(r); /* 0 <= temp <= (base-1)^2 */ + temp += *--uPtr; /* 0 <= temp <= base(base-1) */ + r = uModDiv(temp, d, --qPtr); /* 0 <= r < base */ + } while (uPtr > u->value); +#else + r = memdivw1(q->value, u->value, m, d); +#endif + /* + * normalize q + */ + if (m > 1 && q->value[m-1] == 0) { + --(q->size); + } + q->sign = (u->sign != (v < 0)); + if (q->size == 1 && *(q->value) == 0) q->sign = false; +done: + pdestroy(u); + return presult(q); +} |
