[GRASS-dev] Overflow warning in r.mapcalc calculation

Glynn Clements glynn at gclements.plus.com
Thu May 16 02:58:49 PDT 2013

Rainer M Krug wrote:

> > The round() function always returns an integer, regardless of its
> > argument types. Integers are always 32-bit, so the result is limited
> > to the range +/- 2147483647 (2^31-1).
> True - but is there an equivalent function to round numbers outside the
> integer range?


> Would be useful. Looking at the functions in r.mapcalc, I can't
> think of a way of doing this?

outmap = eval(d = inmap % 1.0, dd = if(d < 0,d+1,d), inmap - dd + if(dd > 0.5,1,0))

The added complexity is because the % operator returns a negative
value for a negative numerator. Specifically, a % b = a - int(a/b)*b,
where conversion to an integer rounds toward zero.

It's not clear whether this behaviour is intentional or just how it
turned out. This is how C's % operator is defined for integer
arguments (for floating-point values, the fmod() library function
behaves similarly).

Also: r.mapcalc's % operator will fail if a/b overflows the range of
an integer. That should be fixed

> I just looked at the round function in xround.c, and it does not look to
> complicated to modify round() to obtain have three more functions, aligned to the
> R functions:

One option is to modify round() to take a second argument (defaulting
to 1), and have it return the first argument rounded to the nearest
multiple of the second. The return type would be that of the second
argument, i.e. round(x,1) rounds to the nearest integer and returns an
integer, round(x,1.0) rounds to the nearest integer and returns a
float, round(x,1e-3) would round to 3 decimal places (i.e. the nearest
multiple of 0.001), etc.

Glynn Clements <glynn at gclements.plus.com>

More information about the grass-dev mailing list