[gnumeric] Complex: fix precision of stringification.



commit 322f0f0cfa0c6f5b2c479166a4ab4409bffadc08
Author: Morten Welinder <terra gnome org>
Date:   Thu Apr 11 09:25:47 2013 -0400

    Complex: fix precision of stringification.
    
    This ensures that stringification+parse round trips.

 ChangeLog                      |    6 ++++++
 NEWS                           |    1 +
 plugins/fn-complex/functions.c |    7 ++-----
 plugins/fn-tsa/functions.c     |    5 +----
 src/complex.c                  |   15 +++++++++++----
 src/complex.h                  |    3 +--
 6 files changed, 22 insertions(+), 15 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 52d3305..77a227f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2013-04-11  Morten Welinder  <terra gnome org>
+
+       * src/complex.c (complex_to_string): Drop format arguments.  All
+       callers changed.  Make up a format with enough precision for round
+       tripping.  Fixes #697634.
+
 2013-04-09  Morten Welinder  <terra gnome org>
 
        * src/complex.c (complex_from_string): Make this handle embedded
diff --git a/NEWS b/NEWS
index 93e35aa..3d6e22a 100644
--- a/NEWS
+++ b/NEWS
@@ -32,6 +32,7 @@ Morten:
        * Fix import of non-Excel functions from LO's xls files.
        * Fix problem with xls saving of externnames.
        * Fix saving of certain XL2007 functions like IFERROR.
+       * Ensure full precision for complex numbers.  [#697634]
 
 --------------------------------------------------------------------------
 Gnumeric 1.12.1
diff --git a/plugins/fn-complex/functions.c b/plugins/fn-complex/functions.c
index 206b6cd..8da2f45 100644
--- a/plugins/fn-complex/functions.c
+++ b/plugins/fn-complex/functions.c
@@ -68,11 +68,8 @@ value_new_complex (complex_t const *c, char imunit)
                return value_new_error_NUM (NULL);
        else if (complex_real_p (c))
                return value_new_float (c->re);
-       else {
-               char f[5 + 4 * sizeof (int) + sizeof (GNM_FORMAT_g)];
-               sprintf (f, "%%.%d" GNM_FORMAT_g, GNM_DIG);
-               return value_new_string_nocopy (complex_to_string (c, f, f, imunit));
-       }
+       else
+               return value_new_string_nocopy (complex_to_string (c, imunit));
 }
 
 /***************************************************************************/
diff --git a/plugins/fn-tsa/functions.c b/plugins/fn-tsa/functions.c
index 6186b80..f69f26d 100644
--- a/plugins/fn-tsa/functions.c
+++ b/plugins/fn-tsa/functions.c
@@ -853,8 +853,6 @@ gnumeric_fourier (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
        int const cols = value_area_get_width (Pt, ep);
        int const rows = value_area_get_height (Pt, ep);
 
-       char f[5 + 4 * sizeof (int) + sizeof (GNM_FORMAT_g)];
-
        if (cols != 1 && rows != 1) {
                res = value_new_error_std (ei->pos, GNM_ERROR_VALUE);
                return res;
@@ -901,10 +899,9 @@ gnumeric_fourier (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
 
        if (out && !sep_columns) {
                res = value_new_array_empty (1 , nb);
-               sprintf (f, "%%.%d" GNM_FORMAT_g, GNM_DIG);
                for (i = 0; i < nb; i++)
                        res->v_array.vals[0][i] = value_new_string_nocopy
-                               (complex_to_string (&(out[i]), f, f, 'i'));
+                               (complex_to_string (&(out[i]), 'i'));
                g_free (out);
        } else if (out && sep_columns) {
                res = value_new_array_empty (2 , nb);
diff --git a/src/complex.c b/src/complex.c
index 9ae8c8f..739324e 100644
--- a/src/complex.c
+++ b/src/complex.c
@@ -18,8 +18,7 @@
 /* ------------------------------------------------------------------------- */
 
 char *
-complex_to_string (complex_t const *src, char const *reformat,
-                  char const *imformat, char imunit)
+complex_to_string (complex_t const *src, char imunit)
 {
        char *re_buffer = NULL;
        char *im_buffer = NULL;
@@ -27,10 +26,18 @@ complex_to_string (complex_t const *src, char const *reformat,
        char const *suffix = "";
        char *res;
        char suffix_buffer[2];
+       const char *fmt = "%.*" GNM_FORMAT_g;
+       static int digits = -1;
+
+       if (digits == -1) {
+               gnm_float l10 = gnm_log10 (FLT_RADIX);
+               digits = (int)gnm_ceil (GNM_MANT_DIG * l10) +
+                       (l10 == (int)l10 ? 0 : 1);
+       }
 
        if (src->re != 0 || src->im == 0) {
                /* We have a real part.  */
-               re_buffer = g_strdup_printf (reformat, src->re);
+               re_buffer = g_strdup_printf (fmt, digits, src->re);
        }
 
        if (src->im != 0) {
@@ -44,7 +51,7 @@ complex_to_string (complex_t const *src, char const *reformat,
                } else if (src->im == -1) {
                        sign = "-";
                } else {
-                       im_buffer = g_strdup_printf (imformat, src->im);
+                       im_buffer = g_strdup_printf (fmt, digits, src->im);
                        if (re_buffer && *im_buffer != '-' && *im_buffer != '+')
                                sign = (src->im >= 0) ? "+" : "-";
                }
diff --git a/src/complex.h b/src/complex.h
index aca5d11..7efafc4 100644
--- a/src/complex.h
+++ b/src/complex.h
@@ -60,8 +60,7 @@ G_BEGIN_DECLS
 
 /* ------------------------------------------------------------------------- */
 
-char *complex_to_string (complex_t const *src, char const *reformat,
-                        char const *imformat, char imunit);
+char *complex_to_string (complex_t const *src, char imunit);
 
 int complex_from_string (complex_t *dst, char const *src, char *imunit);
 


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