[GRASS-dev] output precision of r.info and r.univar

Hi,

to gain more precision when using r.info -r and r.univar -g output in
scripts, I want to suggest this change:

Index: r.info/main.c

--- r.info/main.c (revision 33591)
+++ r.info/main.c (working copy)
@@ -330,8 +330,8 @@
                }
            }
            else {
- fprintf(out, "min=%f\n", zmin);
- fprintf(out, "max=%f\n", zmax);
+ fprintf(out, "min=%.10f\n", zmin);
+ fprintf(out, "max=%.10f\n", zmax);
            }
        }

Index: r.univar2/stats.c

--- r.univar2/stats.c (revision 33591)
+++ r.univar2/stats.c (working copy)
@@ -110,14 +110,14 @@
     if (param.shell_style->answer) {
        fprintf(stdout, "n=%d\n", stats->n);
        fprintf(stdout, "null_cells=%d\n", stats->size - stats->n);
- fprintf(stdout, "min=%g\n", stats->min);
- fprintf(stdout, "max=%g\n", stats->max);
- fprintf(stdout, "range=%g\n", stats->max - stats->min);
- fprintf(stdout, "mean=%g\n", mean);
- fprintf(stdout, "mean_of_abs=%g\n", stats->sum_abs / stats->n);
- fprintf(stdout, "stddev=%g\n", stdev);
- fprintf(stdout, "variance=%g\n", variance);
- fprintf(stdout, "coeff_var=%g\n", var_coef);
+ fprintf(stdout, "min=%.10f\n", stats->min);
+ fprintf(stdout, "max=%.10f\n", stats->max);
+ fprintf(stdout, "range=%.10f\n", stats->max - stats->min);
+ fprintf(stdout, "mean=%.10f\n", mean);
+ fprintf(stdout, "mean_of_abs=%.10f\n", stats->sum_abs / stats->n);
+ fprintf(stdout, "stddev=%.10f\n", stdev);
+ fprintf(stdout, "variance=%.10f\n", variance);
+ fprintf(stdout, "coeff_var=%.10f\n", var_coef);
        fprintf(stdout, "sum=%s\n", sum_str);
     }
     else {

--------------
Before:
r.info -r tmp1
min=0.000002
max=75.527772

r.univar -g mymap | grep min | cut -d'=' -f2
2.72222

After:
r.info -r tmp1
min=0.0000020898
max=75.5277723706

r.univar -g mymap | grep min | cut -d'=' -f2
2.7222220898

Any objections?

Markus

On Wed, Oct 8, 2008 at 9:48 AM, Markus Neteler <neteler@osgeo.org> wrote:

Hi,

to gain more precision when using r.info -r and r.univar -g output in
scripts, I want to suggest this change:

Index: r.info/main.c

--- r.info/main.c (revision 33591)
+++ r.info/main.c (working copy)
@@ -330,8 +330,8 @@
               }
           }
           else {
- fprintf(out, "min=%f\n", zmin);
- fprintf(out, "max=%f\n", zmax);
+ fprintf(out, "min=%.10f\n", zmin);
+ fprintf(out, "max=%.10f\n", zmax);
           }
       }

Index: r.univar2/stats.c

--- r.univar2/stats.c (revision 33591)
+++ r.univar2/stats.c (working copy)
@@ -110,14 +110,14 @@
    if (param.shell_style->answer) {
       fprintf(stdout, "n=%d\n", stats->n);
       fprintf(stdout, "null_cells=%d\n", stats->size - stats->n);
- fprintf(stdout, "min=%g\n", stats->min);
- fprintf(stdout, "max=%g\n", stats->max);
- fprintf(stdout, "range=%g\n", stats->max - stats->min);
- fprintf(stdout, "mean=%g\n", mean);
- fprintf(stdout, "mean_of_abs=%g\n", stats->sum_abs / stats->n);
- fprintf(stdout, "stddev=%g\n", stdev);
- fprintf(stdout, "variance=%g\n", variance);
- fprintf(stdout, "coeff_var=%g\n", var_coef);
+ fprintf(stdout, "min=%.10f\n", stats->min);
+ fprintf(stdout, "max=%.10f\n", stats->max);
+ fprintf(stdout, "range=%.10f\n", stats->max - stats->min);
+ fprintf(stdout, "mean=%.10f\n", mean);
+ fprintf(stdout, "mean_of_abs=%.10f\n", stats->sum_abs / stats->n);
+ fprintf(stdout, "stddev=%.10f\n", stdev);
+ fprintf(stdout, "variance=%.10f\n", variance);
+ fprintf(stdout, "coeff_var=%.10f\n", var_coef);
       fprintf(stdout, "sum=%s\n", sum_str);
    }
    else {

--------------
Before:
r.info -r tmp1
min=0.000002
max=75.527772

r.univar -g mymap | grep min | cut -d'=' -f2
2.72222

After:
r.info -r tmp1
min=0.0000020898
max=75.5277723706

r.univar -g mymap | grep min | cut -d'=' -f2
2.7222220898

Any objections?

I just found Glynn's comment:

On Wed, Oct 8, 2008 at 9:36 AM, Glynn Clements <glynn@gclements.plus.com> wrote:
...

Too much precision is ugly. Too little precision makes it impossible
to use small values. A general-purpose conversion routine such as this
needs to handle the full range of floating-point values, which
basically means %.15g.

So should I go for that?

Markus

Markus Neteler wrote:

I just found Glynn's comment:

On Wed, Oct 8, 2008 at 9:36 AM, Glynn Clements <glynn@gclements.plus.com> wrote:
...
> Too much precision is ugly. Too little precision makes it impossible
> to use small values. A general-purpose conversion routine such as this
> needs to handle the full range of floating-point values, which
> basically means %.15g.

So should I go for that?

Yes.

%f is only useful in situations where you know the range and precision
of the values involved. E.g. for coordinates, you know that they won't
exceed the circumference of the earth, and that the precision doesn't
need to be better than a millimetre, if that.

But cell values can be arbitrary quantities; 1e20 and 1e-20 are both
entirely plausible. And statistical aggregates of those values can
have an even greater range (e.g. sum can be much larger than an
individual value, stddev can be much smaller, and variance can be
massively larger or smaller due to the squaring).

--
Glynn Clements <glynn@gclements.plus.com>