# [GRASS-dev] [GRASS GIS] #1976: r.mapcalc: Allow rounding of floating numbers

GRASS GIS trac at osgeo.org
Tue May 21 06:24:03 PDT 2013

```#1976: r.mapcalc: Allow rounding of floating numbers
-------------------------+--------------------------------------------------
Reporter:  pvanbosgeo   |       Owner:  grass-dev@…
Type:  enhancement  |      Status:  new
Priority:  normal       |   Milestone:  7.0.0
Component:  Raster       |     Version:  unspecified
Keywords:  r.mapcalc    |    Platform:  Unspecified
Cpu:  Unspecified  |
-------------------------+--------------------------------------------------

Comment(by glynn):

Replying to [comment:2 mmetz]:

> The output type of round() is now the same like the input type.

This changes long-standing behaviour in a way which could break scripts.
E.g. if k is an integer,
{{{
round(x) / k
}}}
would always evaluate to an integer, whereas now it may result in a
fraction.

> Rounding to a given number of decimal places is supported with round(x,
y)

From the mailing list discussion ...

Rounding to a given number of decimals is unnecessarily limiting. The
algorithm for generalised rounding is essentially:
{{{
roundTo(x, k) = round(x / k) * k.
}}}
Rounding to N decimal places is just a case of using k=1/10^N^. If you
allow k to be specified directly, then you can round to arbitrary
steps (e.g. k=5 would round to the nearest multiple of 5, etc).

However: there's a slight problem with doing it that way: 0.1 isn't
exactly representable in binary, so e.g. x/0.1 isn't equal to x*10; it
would be more accurate to use:
{{{
roundTo(x, k) = round(x * k) / k
}}}
where k is the reciprocal of the step, so k=10^N^ to round to N decimal
places (or k=2 to round to 1/2).

The downside is that the interface is less useful if you want to round
to something other than a fixed number of decimal places. E.g. if you
wanted to round to the nearest multiple of 45 degrees, you'd need to
use k=1.0/45, which isn't exactly representable.

Unless someone has a better idea, I plan to change the round() function so
that the second argument is the step value, and add an roundi() (round-
inverse) function where the second argument is the reciprocal of the step
value (to avoid the rounding error when using a step of 10^-N^).

--
Ticket URL: <http://trac.osgeo.org/grass/ticket/1976#comment:4>
GRASS GIS <http://grass.osgeo.org>

```