[goffice] Quad: improve prevention of intermediate overflow in pow.



commit 6a81e74417dced521dcd041e419b9226afed9fd2
Author: Morten Welinder <terra gnome org>
Date:   Thu Dec 12 10:39:11 2013 -0500

    Quad: improve prevention of intermediate overflow in pow.

 ChangeLog                 |    6 +++++-
 goffice/math/go-complex.c |   16 ++++++----------
 2 files changed, 11 insertions(+), 11 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 4bb188b..4005886 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
-2013-12-12  Jean Brefort  <jean brefort normalesup org>
+2013-12-12  Morten Welinder  <terra gnome org>
+
+       * goffice/math/go-complex.c (go_complex_pow): Improve prevention
+       of intermediate overflow.
 
+2013-12-12  Jean Brefort  <jean brefort normalesup org>
 
        * plugins/plot_distrib/gog-boxplot.c
        (gog_box_plot_axis_get_bounds): fix crasher [#720310],
diff --git a/goffice/math/go-complex.c b/goffice/math/go-complex.c
index ceb3501..b93859f 100644
--- a/goffice/math/go-complex.c
+++ b/goffice/math/go-complex.c
@@ -381,7 +381,7 @@ SUFFIX(go_complex_pow) (COMPLEX *dst, COMPLEX const *a, COMPLEX const *b)
                        SUFFIX(go_complex_div) (dst, &one, &t);
                }
        } else {
-               DOUBLE res_r, res_a;
+               DOUBLE res_r, res_a, e1, e2;
                SUFFIX(GOQuad) qr, qa, qb, qarg;
                void *state = SUFFIX(go_quad_start) ();
 
@@ -390,19 +390,15 @@ SUFFIX(go_complex_pow) (COMPLEX *dst, COMPLEX const *a, COMPLEX const *b)
                SUFFIX(go_quad_atan2pi) (&qarg, &qb, &qa);
                SUFFIX(go_quad_hypot) (&qr, &qa, &qb);
 
-               /*
-                * This is the square root of the power we really want,
-                * but it is much less likely to cause overflow.
-                */
-               SUFFIX(go_quad_init) (&qa, b->re / 2);
-               SUFFIX(go_quad_pow) (&qa, NULL, &qr, &qa);
+               SUFFIX(go_quad_init) (&qa, b->re);
+               SUFFIX(go_quad_pow) (&qa, &e1, &qr, &qa);
                SUFFIX(go_quad_init) (&qb, -b->im);
                SUFFIX(go_quad_mul) (&qb, &qb, &qarg);
                SUFFIX(go_quad_mul) (&qb, &qb, &SUFFIX(go_quad_pi));
-               SUFFIX(go_quad_exp) (&qb, NULL, &qb);
+               SUFFIX(go_quad_exp) (&qb, &e2, &qb);
                SUFFIX(go_quad_mul) (&qb, &qa, &qb);
-               SUFFIX(go_quad_mul) (&qb, &qa, &qb);
-               res_r = SUFFIX(go_quad_value) (&qb);
+               res_r = SUFFIX(ldexp) (SUFFIX(go_quad_value) (&qb),
+                                      CLAMP (e1 + e2, G_MININT, G_MAXINT));
 
                SUFFIX(go_quad_log) (&qa, &qr);
                SUFFIX(go_quad_div) (&qa, &qa, &SUFFIX(go_quad_2pi));


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