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

Glynn Clements glynn.clements at virgin.net
Thu Nov 7 11:14:10 EST 2002

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,

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 at virgin.net>

More information about the grass-user mailing list