summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Kaivo <jkk@ung.org>2022-03-28 15:13:42 -0400
committerJakob Kaivo <jkk@ung.org>2022-03-28 15:13:42 -0400
commit51d1dee7efbf0e76febfcfc03b32a2f5733461d2 (patch)
treeb5c72ad802ed33cb72b0fd09871e6d2794dc6bb5
parent4a9e7da4421619ed7a0ab9a02d808b77df93e867 (diff)
modernize biglog() and biglog10()
-rw-r--r--big.c52
1 files changed, 32 insertions, 20 deletions
diff --git a/big.c b/big.c
index 1e4eb33..24e5278 100644
--- a/big.c
+++ b/big.c
@@ -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) */