diff options
-rw-r--r-- | big.c | 52 |
1 files changed, 32 insertions, 20 deletions
@@ -17,8 +17,6 @@ #define MAX_INT_BITS 60 #define LONG_LONG_OVERFLOW (1ll<<MAX_INT_BITS) -static double logIBASE; -static double log10IBASE; word big_one; static word big_plus(word, word, int); @@ -33,8 +31,6 @@ static word stimes(word, word); void bigsetup(void) { - logIBASE = log((double)IBASE); - log10IBASE = log10((double)IBASE); big_one = make(INT, 1, 0); } @@ -677,28 +673,44 @@ word dbltobig(double x) the exact integers. There are inherent deficiences in 64 bit fp, no point in trying to mask this */ -double biglog(x) /* logarithm of big x */ -word x; +static double big__log(word x, double logbase, const char *name, double (*fn)(double)) { word n = 0; double r = digit(x); - if (big_is_negative(x) || bigzero(x)) - errno = EDOM, math_error("log"); - while (x = rest(x)) - n++, r = digit(x) + r / IBASE; - return (log(r) + n * logIBASE); + + if (big_is_negative(x) || bigzero(x)) { + errno = EDOM; + math_error(name); + } + + while ((x = rest(x)) != 0) { + n++; + r = digit(x) + r / IBASE; + } + + return (fn(r) + n * logbase); } -double biglog10(x) /* logarithm of big x */ -word x; +/* logarithm of big x */ +double biglog(word x) { - word n = 0; - double r = digit(x); - if (big_is_negative(x) || bigzero(x)) - errno = EDOM, math_error("log10"); - while (x = rest(x)) - n++, r = digit(x) + r / IBASE; - return (log10(r) + n * log10IBASE); + static double logIBASE = 0.0; + if (logIBASE == 0.0) { + logIBASE = log((double)IBASE); + } + + return big__log(x, logIBASE, "log", log); +} + +/* logarithm of big x */ +double biglog10(word x) +{ + static double log10IBASE = 0.0; + if (log10IBASE == 0.0) { + log10IBASE = log10((double)IBASE); + } + + return big__log(x, log10IBASE, "log10", log10); } word bigscan(p) /* read a big number (in decimal) */ |