[GRASSLIST:3632] Re: very low fp values problem

Glynn Clements glynn.clements at virgin.net
Tue Jun 8 23:12:21 EDT 2004


Maciek Sieczka wrote:

> > The simplest workaround would be to scale the values by a large
> > constant such that printf("%f") retains sufficient accuracy.
> 
> could you please explain what is that 'printf("%f")'?

printf() is a standard ANSI C library function for formatting text. It
accepts a variable number arguments, the first of which is a "format
string", which may contain "conversion specifiers" (which start with a
"%" sign). It prints (on the terminal) the format string, but with
each conversion specifier replaced with a textual representation of
the corresponding argument.

For example:

	printf("You scored %d out of %d\n", score, total);

If "score" had the value 8, and "total" had the value 10, it would
print:

	You scored 8 out of 10

The "%f" conversion specifier causes it to display a floating-point
value in decimal notation, to six decimal places. "%.10f" is similar,
except that it uses ten decimal places.

That's probably more information than you wanted to know. What matters
is that "r.stats -1n" (which is how r.univar gets the data) only
displays values to ten decimal places (and many other programs may
only use six, as that is the default for printf's "%f" specifier,
which is the way that most programs convert floating-point values to
text).

So, if your values are of the order of ten-to-the-minus-N, where N is
more than ten, r.stats will simply output one long stream of
"0.0000000000" values, with all of the significant digits being lost.

While printf() can display values in exponential form (e.g. 1.2e-10)
using the "%e" specifier, and awk (which r.univar uses to perform the
actual calculation) can read that form, r.stats doesn't have an option
to use it.

Maybe someone will consider extending r.stats to allow the use of "%e"
(or "%g", which uses ordinary decimal notation for values between
0.0001 and 1000000, and exponential notation otherwise).

But, until then, r.univar will effectively round all of your data to
zero. So, you need to scale it upwards so that the significant digits
appear further to the left.

> > The maximum value is mapped to an intensity value of exactly 255, but
> > rounding error in the lookup probably results in a value of 254.9999,
> > which gets truncated to 254.
> 
> > I suspect that G__interpolate_color_rule() should probably be rounding
> > the result to the nearest integer, rather than truncating it.
> 
> absolutely! rounded is closer to the actual value than the trunctated one,
> isn't it?
> 
> Is there a way to learn about the value range etc. in case of such a low
> value raster in Grass 5.03?

I don't know. The range is actually stored as binary data, so the
information exists. However, r.info displays it using "%f", so small
values will be rounded to zero. I don't know of any other program
which will provide this information.

> Hamish suggested I should try compiling the new version of r.univar in
> src/raster/r.univar2 - would that do? (But then I have to go for the Grass
> 5.3, right?)

Yes. r.univar2 is a C program, and so doesn't suffer from the problem
which the r.univar script has (i.e. that the values are passed from
r.stats to awk as text, using decimal notation).

-- 
Glynn Clements <glynn.clements at virgin.net>




More information about the grass-user mailing list