Quadratic algorithm supports sign, as does decimal conversion.
authorBen Lynn <benlynn@gmail.com>
Tue, 16 Sep 2008 10:22:28 +0000 (16 03:22 -0700)
committerBen Lynn <benlynn@gmail.com>
Tue, 16 Sep 2008 10:22:28 +0000 (16 03:22 -0700)
Better bihom_test.

bihom.c
bihom_test.c
cf.c
cf.h
famous_test.c
mobius.c
test.c

diff --git a/bihom.c b/bihom.c
index 652040d..96c8942 100644 (file)
--- a/bihom.c
+++ b/bihom.c
@@ -90,6 +90,30 @@ static void *bihom(cf_t cf) {
     mpz_set(p->r0, p->p0);  mpz_set(p->r1, p->p1);
     mpz_set(p->p0, t0);     mpz_set(p->p1, t1);
   }
+  // Determine sign.
+  while (mpz_sgn(p->p1) != mpz_sgn(p->q1)
+      || mpz_sgn(p->q1) != mpz_sgn(p->r1)
+      || mpz_sgn(p->r1) != mpz_sgn(p->s1)
+      || mpz_sgn(p->p0) != mpz_sgn(p->q0)
+      || mpz_sgn(p->q0) != mpz_sgn(p->r0)
+      || mpz_sgn(p->r0) != mpz_sgn(p->s0)) {
+    move_right();
+    move_down();
+  }
+  if (mpz_sgn(p->p0) < 0) {
+    mpz_neg(p->p0, p->p0);
+    mpz_neg(p->q0, p->q0);
+    mpz_neg(p->r0, p->r0);
+    mpz_neg(p->s0, p->s0);
+    cf_flip_sign(cf);
+  }
+  if (mpz_sgn(p->p1) < 0) {
+    mpz_neg(p->p1, p->p1);
+    mpz_neg(p->q1, p->q1);
+    mpz_neg(p->r1, p->r1);
+    mpz_neg(p->s1, p->s1);
+    cf_flip_sign(cf);
+  }
 
   int recur() {
     if (!mpz_sgn(p->s1)) {
index 874beee..10548f1 100644 (file)
@@ -22,7 +22,7 @@ int main() {
 
   cf_t b = cf_new_bihom(e, pi, addarray);
 
-  CF_EXPECT_DEC(b, "58598744820488384738");
+  CF_EXPECT_DEC(b, "5.8598744820488384738");
 
   cf_free(b);
   cf_free(e);
@@ -38,11 +38,26 @@ int main() {
   mpz_set_si(addarray[7], 1);
   b = cf_new_bihom(s1, c1, addarray);
 
-  CF_EXPECT_DEC(b, "09092974268256816953");
+  CF_EXPECT_DEC(b, "0.9092974268256816953");
 
   cf_free(b);
   cf_free(c1);
   cf_free(s1);
+
+  // Check 2 (cos 1)^2 - 1 = cos 2 =
+  s1 = cf_new_cos1();  // TODO: Implement tee, use that instead.
+  c1 = cf_new_cos1();
+  mpz_set_si(addarray[0], 2);
+  mpz_set_si(addarray[3], -1);
+  mpz_set_si(addarray[7], 1);
+  b = cf_new_bihom(s1, c1, addarray);
+
+  CF_EXPECT_DEC(b, "-0.41614683654714238699");
+
+  cf_free(b);
+  cf_free(c1);
+  cf_free(s1);
+
   for (int i = 0; i < 8; i++) {
     mpz_clear(addarray[i]);
   }
diff --git a/cf.c b/cf.c
index 2bad1b5..780f2c5 100644 (file)
--- a/cf.c
+++ b/cf.c
@@ -44,6 +44,10 @@ void *cf_data(cf_t cf) {
   return cf->data;
 }
 
+void cf_set_sign(cf_t cf, int sign) {
+  cf->sign = sign;
+}
+
 int cf_sign(cf_t cf) {
   return cf->sign;
 }
diff --git a/cf.h b/cf.h
index 1fd64e3..c319414 100644 (file)
--- a/cf.h
+++ b/cf.h
@@ -14,6 +14,7 @@ static inline cf_t cf_new_const(void *(*func)(cf_t)) {
 }
 void cf_free(cf_t cf);
 
+void cf_set_sign(cf_t cf, int sign);
 int cf_sign(cf_t cf);
 int cf_flip_sign(cf_t cf);
 void cf_get(mpz_t z, cf_t cf);
index ec2ac79..10db391 100644 (file)
@@ -9,11 +9,11 @@
 #include "test.h"
 
 int main() {
-  CF_NEW_EXPECT_DEC(cf_new_e, "2718281828");
-  CF_NEW_EXPECT_DEC(cf_new_pi, "31415926535897932384");
-  CF_NEW_EXPECT_DEC(cf_new_tan1, "15574077246549022305");
+  CF_NEW_EXPECT_DEC(cf_new_e, "2.718281828");
+  CF_NEW_EXPECT_DEC(cf_new_pi, "3.1415926535897932384");
+  CF_NEW_EXPECT_DEC(cf_new_tan1, "1.5574077246549022305");
 
-  CF_NEW_EXPECT_DEC(cf_new_sin1, "08414709848078965066");
-  CF_NEW_EXPECT_DEC(cf_new_cos1, "05403023058681397174");
+  CF_NEW_EXPECT_DEC(cf_new_sin1, "0.8414709848078965066");
+  CF_NEW_EXPECT_DEC(cf_new_cos1, "0.5403023058681397174");
   return 0;
 }
index 23b8373..8507449 100644 (file)
--- a/mobius.c
+++ b/mobius.c
@@ -242,6 +242,7 @@ static void *mobius_decimal(cf_t cf) {
   mpz_t t0, t1, t2; mpz_init(t2); mpz_init(t1); mpz_init(t0);
 
   // Determine the sign.
+  cf_set_sign(cf, cf_sign(input));
   while (mpz_sgn(pq->pold) != mpz_sgn(pq->p)
       || mpz_sgn(pq->qold) != mpz_sgn(pq->q)) {
     cf_get(denom, input);
diff --git a/test.c b/test.c
index 075c714..ec4d43c 100644 (file)
--- a/test.c
+++ b/test.c
@@ -10,11 +10,28 @@ void cf_expect_dec(cf_t x, char *result, char *filename, int line) {
   cf_t conv;
   conv = cf_new_cf_to_decimal(x);
   int len = strlen(result);
+
   char s[len + 1];
-  for (int i = 0; i <= len; i++) {
+  cf_get(z, conv);
+  int i = 0;
+  if (cf_sign(conv) < 0) {
+    s[i] = '-';
+    i++;
+  }
+  if (i >= len) goto testit;
+  i += gmp_snprintf(s + i, len - i + 1, "%Zd", z);
+  if (i >= len) goto testit;
+  s[i] = '.';
+  i++;
+  if (i >= len) goto testit;
+
+  while (i < len) {
     cf_get(z, conv);
     s[i] = mpz_get_ui(z) + '0';
+    i++;
   }
+
+testit:
   s[len] = 0;
   if (strcmp(s, result)) {
     fprintf(stderr, "\n%s:%d: bad continued fraction decimal expansion\n",