void negate(RR& z, const RR& a) { xcopy(z, a); negate(z.x, z.x); }
void abs(RR& z, const RR& a) { xcopy(z, a); abs(z.x, z.x); }
void conv(RR& x, const char *s) { long c; long cval; long sign; ZZ a, b; long i = 0; if (!s) Error("bad RR input"); c = s[i]; while (IsWhiteSpace(c)) { i++; c = s[i]; } if (c == '-') { sign = -1; i++; c = s[i]; } else sign = 1; long got1 = 0; long got_dot = 0; long got2 = 0; a = 0; b = 1; cval = CharToIntVal(c); if (cval >= 0 && cval <= 9) { got1 = 1; while (cval >= 0 && cval <= 9) { mul(a, a, 10); add(a, a, cval); i++; c = s[i]; cval = CharToIntVal(c); } } if (c == '.') { got_dot = 1; i++; c = s[i]; cval = CharToIntVal(c); if (cval >= 0 && cval <= 9) { got2 = 1; while (cval >= 0 && cval <= 9) { mul(a, a, 10); add(a, a, cval); mul(b, b, 10); i++; c = s[i]; cval = CharToIntVal(c); } } } if (got_dot && !got1 && !got2) Error("bad RR input"); ZZ e; long got_e = 0; long e_sign; if (c == 'e' || c == 'E') { got_e = 1; i++; c = s[i]; if (c == '-') { e_sign = -1; i++; c = s[i]; } else if (c == '+') { e_sign = 1; i++; c = s[i]; } else e_sign = 1; cval = CharToIntVal(c); if (cval < 0 || cval > 9) Error("bad RR input"); e = 0; while (cval >= 0 && cval <= 9) { mul(e, e, 10); add(e, e, cval); i++; c = s[i]; cval = CharToIntVal(c); } } if (!got1 && !got2 && !got_e) Error("bad RR input"); RR t1, t2, v; long old_p = RR::precision(); if (got1 || got2) { ConvPrec(t1, a, max(NumBits(a), 1)); ConvPrec(t2, b, NumBits(b)); if (got_e) RR::SetPrecision(old_p + 10); div(v, t1, t2); } else set(v); if (sign < 0) negate(v, v); if (got_e) { if (e >= NTL_OVFBND) Error("RR input overflow"); long E; conv(E, e); if (e_sign < 0) E = -E; RR::SetPrecision(old_p + 10); power(t1, to_RR(10), E); mul(v, v, t1); RR::prec = old_p; } xcopy(x, v); }
void sin(RR& res, const RR& x) { if (x == 0) { res = 0; return; } if (Lg2(x) > 1000) Error("sin: sorry...argument too large in absolute value"); long p = RR::precision(); RR pi, t1, f; RR n; // we want to make x^2 < 3, so that the series for sin(x) // converges nicely, without any nasty cancellations in the // first terms of the series. RR::SetPrecision(p + NumBits(p) + 10); if (x*x < 3) { xcopy(f, x); } else { // we want to write x/pi = n + f, |f| < 1/2.... // but we have to do *this* very carefully, so that f is computed // to precision > p. I know, this is sick! long p1; p1 = p + Lg2(x) + 20; for (;;) { RR::SetPrecision(p1); ComputePi(pi); xcopy(t1, x/pi); xcopy(n, floor(t1)); xcopy(f, t1 - n); if (f > 0.5) { n++; xcopy(f, t1 - n); } if (f == 0 || p1 < p - Lg2(f) + Lg2(n) + 10) { // we don't have enough bits of f...increase p1 and continue p1 = p1 + max(20, p1/10); } else break; } RR::SetPrecision(p + NumBits(p) + 10); ComputePi(pi); xcopy(f, pi * f); if (n != 0 && n.exponent() == 0) { // n is odd, so we negate f, which negates sin(f) xcopy(f, -f); } } // Boy, that was painful, but now its over, and we can simply apply // the series for sin(f) RR t2, s, s1, t; long i; s = 0; xcopy(t, f); for (i = 3; ; i=i+2) { add(s1, s, t); if (s == s1) break; xcopy(s, s1); mul(t, t, f); mul(t, t, f); div(t, t, i-1); div(t, t, i); negate(t, t); } RR::SetPrecision(p); xcopy(res, s); }
void cos(RR& res, const RR& x) { if (x == 0) { res = 1; return; } if (Lg2(x) > 1000) Error("cos: sorry...argument too large in absolute value"); long p = RR::precision(); RR pi, t1, f; RR n; // we want to write x/pi = (n+1/2) + f, |f| < 1/2.... // but we have to do *this* very carefully, so that f is computed // to precision > p. I know, this is sick! long p1; p1 = p + Lg2(x) + 20; for (;;) { RR::SetPrecision(p1); ComputePi(pi); xcopy(t1, x/pi); xcopy(n, floor(t1)); xcopy(f, t1 - (n + 0.5)); if (f == 0 || p1 < p - Lg2(f) + Lg2(n) + 10) { // we don't have enough bits of f...increase p1 and continue p1 = p1 + max(20, p1/10); } else break; } RR::SetPrecision(p + NumBits(p) + 10); ComputePi(pi); xcopy(f, pi * f); if (n == 0 || n.exponent() != 0) { // n is even, so we negate f, which negates sin(f) xcopy(f, -f); } // Boy, that was painful, but now its over, and we can simply apply // the series for sin(f) RR t2, s, s1, t; long i; s = 0; xcopy(t, f); for (i = 3; ; i=i+2) { add(s1, s, t); if (s == s1) break; xcopy(s, s1); mul(t, t, f); mul(t, t, f); div(t, t, i-1); div(t, t, i); negate(t, t); } RR::SetPrecision(p); xcopy(res, s); }
int main(int argc, char *argv[]) { extern int optind; extern char *optarg; enum S command = COMMAND, state; DB *dbp; DBT data, key, keydata; size_t len; int ch, oflags, sflag; char *fname, *infoarg, *p, *t, buf[8 * 1024]; bool unlink_dbfile; infoarg = NULL; fname = NULL; unlink_dbfile = false; oflags = O_CREAT | O_RDWR; sflag = 0; while ((ch = getopt(argc, argv, "f:i:lo:s")) != -1) switch (ch) { case 'f': fname = optarg; break; case 'i': infoarg = optarg; break; case 'l': oflags |= DB_LOCK; break; case 'o': if ((ofd = open(optarg, O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0) err(1, "Cannot create `%s'", optarg); break; case 's': sflag = 1; break; case '?': default: usage(); } argc -= optind; argv += optind; if (argc != 2) usage(); /* Set the type. */ type = dbtype(*argv++); /* Open the descriptor file. */ if (strcmp(*argv, "-") && freopen(*argv, "r", stdin) == NULL) err(1, "Cannot reopen `%s'", *argv); /* Set up the db structure as necessary. */ if (infoarg == NULL) infop = NULL; else for (p = strtok(infoarg, ",\t "); p != NULL; p = strtok(0, ",\t ")) if (*p != '\0') infop = setinfo(type, p); /* * Open the DB. Delete any preexisting copy, you almost never * want it around, and it often screws up tests. */ if (fname == NULL) { const char *q = getenv("TMPDIR"); if (q == NULL) q = "/var/tmp"; (void)snprintf(buf, sizeof(buf), "%s/__dbtest", q); fname = buf; (void)unlink(buf); unlink_dbfile = true; } else if (!sflag) (void)unlink(fname); if ((dbp = dbopen(fname, oflags, S_IRUSR | S_IWUSR, type, infop)) == NULL) err(1, "Cannot dbopen `%s'", fname); XXdbp = dbp; if (unlink_dbfile) (void)unlink(fname); state = COMMAND; for (lineno = 1; (p = fgets(buf, sizeof(buf), stdin)) != NULL; ++lineno) { /* Delete the newline, displaying the key/data is easier. */ if (ofd == STDOUT_FILENO && (t = strchr(p, '\n')) != NULL) *t = '\0'; if ((len = strlen(buf)) == 0 || isspace((unsigned char)*p) || *p == '#') continue; /* Convenient gdb break point. */ if (XXlineno == lineno) XXlineno = 1; switch (*p) { case 'c': /* compare */ chkcmd(state); state = KEY; command = COMPARE; break; case 'e': /* echo */ chkcmd(state); /* Don't display the newline, if CR at EOL. */ if (p[len - 2] == '\r') --len; if (write(ofd, p + 1, len - 1) != (ssize_t)len - 1 || write(ofd, "\n", 1) != 1) err(1, "write failed"); break; case 'g': /* get */ chkcmd(state); state = KEY; command = GET; break; case 'p': /* put */ chkcmd(state); state = KEY; command = PUT; break; case 'r': /* remove */ chkcmd(state); if (flags == R_CURSOR) { rem(dbp, &key); state = COMMAND; } else { state = KEY; command = REMOVE; } break; case 'S': /* sync */ chkcmd(state); synk(dbp); state = COMMAND; break; case 's': /* seq */ chkcmd(state); if (flags == R_CURSOR) { state = KEY; command = SEQ; } else seq(dbp, &key); break; case 'f': flags = setflags(p + 1); break; case 'D': /* data file */ chkdata(state); data.data = rfile(p + 1, &data.size); goto ldata; case 'd': /* data */ chkdata(state); data.data = xcopy(p + 1, len - 1); data.size = len - 1; ldata: switch (command) { case COMPARE: compare(&keydata, &data); break; case PUT: put(dbp, &key, &data); break; default: errx(1, "line %zu: command doesn't take data", lineno); } if (type != DB_RECNO) free(key.data); free(data.data); state = COMMAND; break; case 'K': /* key file */ chkkey(state); if (type == DB_RECNO) errx(1, "line %zu: 'K' not available for recno", lineno); key.data = rfile(p + 1, &key.size); goto lkey; case 'k': /* key */ chkkey(state); if (type == DB_RECNO) { static recno_t recno; recno = atoi(p + 1); key.data = &recno; key.size = sizeof(recno); } else { key.data = xcopy(p + 1, len - 1); key.size = len - 1; } lkey: switch (command) { case COMPARE: getdata(dbp, &key, &keydata); state = DATA; break; case GET: get(dbp, &key); if (type != DB_RECNO) free(key.data); state = COMMAND; break; case PUT: state = DATA; break; case REMOVE: rem(dbp, &key); if ((type != DB_RECNO) && (flags != R_CURSOR)) free(key.data); state = COMMAND; break; case SEQ: seq(dbp, &key); if ((type != DB_RECNO) && (flags != R_CURSOR)) free(key.data); state = COMMAND; break; default: errx(1, "line %zu: command doesn't take a key", lineno); } break; case 'o': dump(dbp, p[1] == 'r', 0); break; #ifdef __NetBSD__ case 'O': dump(dbp, p[1] == 'r', 1); break; case 'u': unlinkpg(dbp); break; #endif default: errx(1, "line %zu: %s: unknown command character", lineno, p); } } #ifdef STATISTICS /* * -l must be used (DB_LOCK must be set) for this to be * used, otherwise a page will be locked and it will fail. */ if (type == DB_BTREE && oflags & DB_LOCK) __bt_stat(dbp); #endif if ((*dbp->close)(dbp)) err(1, "db->close failed"); (void)close(ofd); return 0; }
void dump_opcodes(FILE *f) { int c, d; char cmdname[16]; char cmdpretty[500]; const char *p; for (c=0; c<65536; c++) { if (isDBL(c)) { const unsigned int cmd = opDBL(c); if ((c & 0xff) != 0) continue; if (cmd >= num_multicmds) continue; #ifdef INCLUDE_MULTI_DELETE if (cmd == DBL_DELPROG) continue; #endif xset(cmdname, '\0', 16); xcopy(cmdname, multicmds[cmd].cmd, NAME_LEN); prettify(cmdname, cmdpretty); fprintf(f, "0x%04x\tmult\t%s\n", c, cmdpretty); } else if (isRARG(c)) { const unsigned int cmd = RARG_CMD(c); unsigned int limit; if (cmd >= NUM_RARG) continue; #ifdef INCLUDE_MULTI_DELETE if (cmd == RARG_DELPROG) continue; #endif limit = argcmds[cmd].lim; if (cmd != RARG_ALPHA && (c & RARG_IND) != 0) continue; p = catcmd(c, cmdname); if (strcmp(p, "???") == 0) continue; prettify(p, cmdpretty); if (cmd == RARG_ALPHA) { if ((c & 0xff) == 0) continue; if ((c & 0xff) == ' ') fprintf(f, "0x%04x\tcmd\t[alpha] [space]\n", c); else fprintf(f, "0x%04x\tcmd\t[alpha] %s\n", c, cmdpretty); continue; } else if (cmd == RARG_CONST || cmd == RARG_CONST_CMPLX) { fprintf(f, "0x%04x\tcmd\t%s# %s\n", c, cmd == RARG_CONST_CMPLX?"[cmplx]":"", cmdpretty); continue; } else if (cmd == RARG_CONV) { fprintf(f, "0x%04x\tcmd\t%s\n", c, cmdpretty); continue; } else if (cmd == RARG_CONST_INT) { p = prt(c, cmdname); if (strcmp(p, "???") != 0) fprintf(f, "0x%04x\tcmd\t%s\n", c, p); if ((c & 0xff) != 0) continue; limit = 0; } if ((c & 0xff) != 0) continue; fprintf(f, "0x%04x\targ\t%s\tmax=%u", c, cmdpretty, limit); if (argcmds[cmd].indirectokay) fprintf(f, ",indirect"); if (argcmds[cmd].stos) fprintf(f, ",stostack"); else if (argcmds[cmd].stckreg) fprintf(f, ",stack"); if (argcmds[cmd].cmplx) fprintf(f, ",complex"); fprintf(f, "\n"); } else { p = catcmd(c, cmdname); if (strcmp(p, "???") == 0) continue; prettify(p, cmdpretty); d = argKIND(c); switch (opKIND(c)) { default: break; case KIND_MON: if (d < num_monfuncs && (! isNULL(monfuncs[d].mondreal) || ! isNULL(monfuncs[d].monint))) break; continue; case KIND_DYA: if (d < num_dyfuncs && (! isNULL(dyfuncs[d].dydreal) || ! isNULL(dyfuncs[d].dydint))) break; continue; case KIND_CMON: if (d < num_monfuncs && ! isNULL(monfuncs[d].mondcmplx)) { if (cmdname[0] == COMPLEX_PREFIX) break; fprintf(f, "0x%04x\tcmd\t[cmplx]%s\n", c, cmdpretty); } continue; case KIND_CDYA: if (d < num_dyfuncs && ! isNULL(dyfuncs[d].dydcmplx)) { if (cmdname[0] == COMPLEX_PREFIX) break; fprintf(f, "0x%04x\tcmd\t[cmplx]%s\n", c, cmdpretty); } continue; case KIND_NIL: d = c & 0xff; if (d == OP_CLALL || d == OP_RESET) { continue; } } fprintf(f, "0x%04x\tcmd\t%s\n", c, cmdpretty); } } }
char* xstrdup(const char* str, size_t expand) { return xcopy(str, strlen(str) + 1, expand); }
/** * This method is like the copy() counterpart. Bytes are read * from a source databuf. * @return SUCCESS or FAILURE if no memory is available * to stretch the buffer. */ int32 xcopy(DataBuf* b) { return xcopy((char *) b->getAddr(), b->getCount()); }
/** * This method is like the copy() counterpart, but sthretches * the buffer if source data are more than this buffer's size. * @return SUCCESS or FAILURE if no memory is available * to stretch the buffer. */ int32 xcopy(char* string) { return xcopy(string, (uint32) strlen(string) + 1); }