[goffice] Complex: expose power function with separate return value for powers of 2.



commit 5dc16947fd988cfc753b076860a43ca3a26afb8f
Author: Morten Welinder <terra gnome org>
Date:   Tue Feb 23 20:32:17 2016 -0500

    Complex: expose power function with separate return value for powers of 2.
    
    This version is effective for computations with really big numbers.

 ChangeLog                 |    5 +++++
 goffice/math/go-complex.c |   28 +++++++++++++++++++++-------
 goffice/math/go-complex.h |    4 ++++
 3 files changed, 30 insertions(+), 7 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index ab83802..065b038 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2016-02-23  Morten Welinder  <terra gnome org>
+
+       * goffice/math/go-complex.c (go_complex_powx): Expose the power
+       function with separate return value for powers of 2.
+
 2016-02-16  Morten Welinder  <terra gnome org>
 
        * goffice/math/go-complex.c: Make a boxed type for the benefit of
diff --git a/goffice/math/go-complex.c b/goffice/math/go-complex.c
index 9726ba1..c845483 100644
--- a/goffice/math/go-complex.c
+++ b/goffice/math/go-complex.c
@@ -351,10 +351,14 @@ SUFFIX(mulmod1) (SUFFIX(GOQuad) *dst, SUFFIX(GOQuad) const *qa_, DOUBLE b)
 }
 
 void
-SUFFIX(go_complex_pow) (COMPLEX *dst, COMPLEX const *a, COMPLEX const *b)
+SUFFIX(go_complex_powx) (COMPLEX *dst, DOUBLE *e,
+                        COMPLEX const *a, COMPLEX const *b)
 {
+       if (e)
+               *e = 0;
+
        if (b->im == 0) {
-               if (SUFFIX(go_complex_real_p) (a) && a->re >= 0) {
+               if (!e && SUFFIX(go_complex_real_p) (a) && a->re >= 0) {
                        SUFFIX(go_complex_init) (dst, SUFFIX(pow) (a->re, b->re), 0);
                        return;
                }
@@ -376,8 +380,7 @@ SUFFIX(go_complex_pow) (COMPLEX *dst, COMPLEX const *a, COMPLEX const *b)
        }
 
        {
-               DOUBLE e1, e2;
-               int e;
+               DOUBLE e1, e2, er;
                SUFFIX(GOQuad) qr, qa, qb, qarg, qrr, qra;
                void *state = SUFFIX(go_quad_start) ();
 
@@ -395,9 +398,14 @@ SUFFIX(go_complex_pow) (COMPLEX *dst, COMPLEX const *a, COMPLEX const *b)
                SUFFIX(go_quad_mul) (&qb, &qb, &SUFFIX(go_quad_pi));
                SUFFIX(go_quad_exp) (&qb, &e2, &qb);
                SUFFIX(go_quad_mul) (&qrr, &qa, &qb);
-               e = CLAMP (e1 + e2, G_MININT, G_MAXINT);
-               qrr.h = SUFFIX(ldexp) (qrr.h, e);
-               qrr.l = SUFFIX(ldexp) (qrr.l, e);
+               er = e1 + e2;
+               if (e)
+                       *e = er;
+               else {
+                       er = CLAMP (er, G_MININT, G_MAXINT);
+                       qrr.h = SUFFIX(ldexp) (qrr.h, er);
+                       qrr.l = SUFFIX(ldexp) (qrr.l, er);
+               }
 
                /* Compute result angle.  */
                SUFFIX(go_quad_log) (&qa, &qr);
@@ -421,6 +429,12 @@ SUFFIX(go_complex_pow) (COMPLEX *dst, COMPLEX const *a, COMPLEX const *b)
        }
 }
 
+void
+SUFFIX(go_complex_pow) (COMPLEX *dst, COMPLEX const *a, COMPLEX const *b)
+{
+       SUFFIX(go_complex_powx) (dst, NULL, a, b);
+}
+
 /* ------------------------------------------------------------------------- */
 
 void SUFFIX(go_complex_init) (COMPLEX *dst, DOUBLE re, DOUBLE im)
diff --git a/goffice/math/go-complex.h b/goffice/math/go-complex.h
index 994df6a..995d57e 100644
--- a/goffice/math/go-complex.h
+++ b/goffice/math/go-complex.h
@@ -34,6 +34,8 @@ void go_complex_from_polar_pi (GOComplex *dst, double mod, double angle);
 void go_complex_mul  (GOComplex *dst, GOComplex const *a, GOComplex const *b);
 void go_complex_div  (GOComplex *dst, GOComplex const *a, GOComplex const *b);
 void go_complex_pow  (GOComplex *dst, GOComplex const *a, GOComplex const *b);
+void go_complex_powx (GOComplex *dst, double *e,
+                     GOComplex const *a, GOComplex const *b);
 void go_complex_sqrt (GOComplex *dst, GOComplex const *src);
 void go_complex_init (GOComplex *dst, double re, double im);
 void go_complex_invalid (GOComplex *dst);
@@ -72,6 +74,8 @@ void go_complex_from_polar_pil (GOComplexl *dst, long double mod, long double an
 void go_complex_mull  (GOComplexl *dst, GOComplexl const *a, GOComplexl const *b);
 void go_complex_divl  (GOComplexl *dst, GOComplexl const *a, GOComplexl const *b);
 void go_complex_powl  (GOComplexl *dst, GOComplexl const *a, GOComplexl const *b);
+void go_complex_powxl  (GOComplexl *dst, long double *e,
+                       GOComplexl const *a, GOComplexl const *b);
 void go_complex_sqrtl (GOComplexl *dst, GOComplexl const *src);
 void go_complex_initl (GOComplexl *dst, long double re, long double im);
 void go_complex_invalidl (GOComplexl *dst);


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