[GRASSLIST:4900] converting null values, is this a bug

Dear all,

I am trying to convert null values to 0 with r.mapcalc. Did I bump into a bug?

rast is a raster containing 1 and null() data, with

r.mapcalc rast.nonull = "if(rast==null(),0,1)"

rast.nonull has 0 categories and:
Range of data: min = -2147483648 max = -2147483648

If I use instead:
r.mapcalc rast.nonull = "if(isnull(rast),0,1)"
the values are then correctly converted from null() to 0.

Why is this?

Best,

Thomas

On Thu, Nov 07, 2002 at 01:15:17PM -0000, Thomas Dewez wrote:

Dear all,

I am trying to convert null values to 0 with r.mapcalc. Did I bump into a bug?

rast is a raster containing 1 and null() data, with

r.mapcalc rast.nonull = "if(rast==null(),0,1)"

Use isnull(). You can't compare null to anything. But, why not use
r.null ?

--
static const char signature =
  "Copyright (c) 2002 Eric G. Miller <egm2@jps.net>";

Thomas Dewez wrote:

I am trying to convert null values to 0 with r.mapcalc. Did I bump into a bug?

rast is a raster containing 1 and null() data, with

r.mapcalc rast.nonull = "if(rast==null(),0,1)"

rast.nonull has 0 categories and:
Range of data: min = -2147483648 max = -2147483648

If I use instead:
r.mapcalc rast.nonull = "if(isnull(rast),0,1)"
the values are then correctly converted from null() to 0.

Why is this?

This is a feature, not a bug.

Like most operators, '==' returns null if either argument is null. If
you bear in mind that null represents "no data" or "unknown", this
makes sense. If x and y are both null, then you don't know what either
x or y are, and so you don't know whether x == y.

If you want to check whether a value is null, use isnull().

The r.mapcalc manpage partially documents the treatment of nulls,
however:

a) It doesn't explicitly describe the semantics of the comparison
operators (unless you consider them to be "arithmetic operators",
which is dubious).

b) The && and || operators don't currently behave as documented; they
both return null if either argument is null. It's debatable as to
which behaviour is preferable, although the documentation should
definitely match the actual behaviour.

In general, the value of an expression which contains nulls should
itself be null if replacing the nulls with differing non-null values
would produce differing results (apart from isnull(), obviously).

The converse isn't always true. It will hold in cases where there's a
straightforward rule, e.g.

a) if() only returns null if the first argument is null, or if the
chosen conditional argument is null, but not if the unchosen
conditional argument is null.

b) eval() only returns null if the last argument is null; IOW, the
other arguments are always ignored.

However, it won't hold in "special" cases, e.g.:

  null * x -> null (even if x == 0)
  null ^ x -> null (even if x == 0)
  if(null, x, y) -> null (even if x == y)
  null < x -> null (even if x is the largest possible value)

[Aside: this is why I consider the "correct" behaviour for && and ||
to be debatable.]

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