[goffice] GOQuad: add floor.



commit cac4ae9e82f262fa59869acf9e60ce9dadc64cd2
Author: Morten Welinder <terra gnome org>
Date:   Tue Nov 5 14:34:27 2013 -0500

    GOQuad: add floor.

 ChangeLog              |    2 +-
 goffice/math/go-quad.c |   39 ++++++++++++++++++++++++++++++++++-----
 goffice/math/go-quad.h |    2 ++
 3 files changed, 37 insertions(+), 6 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index ee7f162..6014dca 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,7 +1,7 @@
 2013-11-04  Morten Welinder  <terra gnome org>
 
        * goffice/math/go-quad.c (go_quad_pow, go_quad_exp)
-       (go_quad_expm1): new functions.
+       (go_quad_expm1, go_quad_floor): new functions.
 
        * goffice/math/go-quad.h (go_quad_one, go_quad_pi, go_quad_e)
        (go_quad_ln2, go_quad_sqrt2, go_quad_euler): Supply a handful of
diff --git a/goffice/math/go-quad.c b/goffice/math/go-quad.c
index 9f4946e..c461f9c 100644
--- a/goffice/math/go-quad.c
+++ b/goffice/math/go-quad.c
@@ -407,6 +407,34 @@ SUFFIX(go_quad_sqrt) (QUAD *res, const QUAD *a)
 }
 
 /**
+ * go_quad_floor: (skip)
+ **/
+/**
+ * go_quad_floorl: (skip)
+ **/
+void
+SUFFIX(go_quad_floor) (QUAD *res, const QUAD *a)
+{
+       QUAD qh, ql, q, r;
+
+       SUFFIX(go_quad_init) (&qh, SUFFIX(floor)(a->h));
+       SUFFIX(go_quad_init) (&ql, SUFFIX(floor)(a->l));
+       SUFFIX(go_quad_add) (&q, &qh, &ql);
+
+       /* Due to dual floors, we might be off by one.  */
+       SUFFIX(go_quad_sub) (&r, a, &q);
+       if (SUFFIX(go_quad_value) (&r) < 0)
+               SUFFIX(go_quad_sub) (res, &q, &SUFFIX(go_quad_one));
+       else {
+               SUFFIX(go_quad_sub) (&r, &r, &SUFFIX(go_quad_one));
+               if (SUFFIX(go_quad_value) (&r) < 0)
+                       *res = q;
+               else
+                       SUFFIX(go_quad_add) (res, &q, &SUFFIX(go_quad_one));
+       }
+}
+
+/**
  * go_quad_dot_product: (skip)
  **/
 /**
@@ -609,7 +637,7 @@ void
 SUFFIX(go_quad_pow) (QUAD *res, DOUBLE *exp2,
                     const QUAD *x, const QUAD *y)
 {
-       DOUBLE dy, w, exp2ew;
+       DOUBLE dy, exp2ew;
        QUAD qw, qf, qew, qef, qxm1;
 
        dy = SUFFIX(go_quad_value) (y);
@@ -621,12 +649,13 @@ SUFFIX(go_quad_pow) (QUAD *res, DOUBLE *exp2,
                return;
        }
 
-       w = SUFFIX(floor) (dy);
-       SUFFIX(go_quad_init) (&qw, w);
+       SUFFIX(go_quad_floor) (&qw, y);
        SUFFIX(go_quad_sub) (&qf, y, &qw);
        if (SUFFIX(go_quad_value) (&qxm1) == 0 && dy > 0) {
-               if (SUFFIX(go_quad_value) (&qf) == 0 &&
-                   SUFFIX(fmod)(SUFFIX(fabs)(w),2) == 1) {
+               gboolean wodd =
+                       (SUFFIX(fmod)(SUFFIX(fabs)(qw.h),2) +
+                        SUFFIX(fmod)(SUFFIX(fabs)(qw.l),2)) == 1;
+               if (SUFFIX(go_quad_value) (&qf) == 0 && wodd) {
                        /* 0 ^ (odd positive integer) */
                        *res = *x;
                } else {
diff --git a/goffice/math/go-quad.h b/goffice/math/go-quad.h
index cf13ad0..1ffe022 100644
--- a/goffice/math/go-quad.h
+++ b/goffice/math/go-quad.h
@@ -22,6 +22,7 @@ void go_quad_sub (GOQuad *res, const GOQuad *a, const GOQuad *b);
 void go_quad_mul (GOQuad *res, const GOQuad *a, const GOQuad *b);
 void go_quad_div (GOQuad *res, const GOQuad *a, const GOQuad *b);
 void go_quad_sqrt (GOQuad *res, const GOQuad *a);
+void go_quad_floor (GOQuad *res, const GOQuad *a);
 void go_quad_pow (GOQuad *res, double *exp2, const GOQuad *x, const GOQuad *y);
 void go_quad_exp (GOQuad *res, double *exp2, const GOQuad *a);
 void go_quad_expm1 (GOQuad *res, const GOQuad *a);
@@ -58,6 +59,7 @@ void go_quad_subl (GOQuadl *res, const GOQuadl *a, const GOQuadl *b);
 void go_quad_mull (GOQuadl *res, const GOQuadl *a, const GOQuadl *b);
 void go_quad_divl (GOQuadl *res, const GOQuadl *a, const GOQuadl *b);
 void go_quad_sqrtl (GOQuadl *res, const GOQuadl *a);
+void go_quad_floorl (GOQuadl *res, const GOQuadl *a);
 void go_quad_powl (GOQuadl *res, long double *exp2, const GOQuadl *x, const GOQuadl *y);
 void go_quad_expl (GOQuadl *res, long double *exp2, const GOQuadl *a);
 void go_quad_expm1l (GOQuadl *res, const GOQuadl *a);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]