I am trying to find out if 2 raster layers are exactly identical. I am not an experienced mapcalc user, so I am wondering, where the 3200204 NULL values come from, in Test1. The result in Test2 is what I expected.
My obviously wrong understanding was that I wouldn't need the special operator ||| in Test1, as NULL values are already treated specially by isnull()
I am trying to find out if 2 raster layers are exactly identical. I am
not an experienced mapcalc user, so I am wondering, where the 3200204
NULL values come from, in Test1. The result in Test2 is what I expected.
My obviously wrong understanding was that I wouldn't need the special
operator ||| in Test1, as NULL values are already treated specially by
isnull()
If mapA and mapT are both null, then Test 1 reduces to:
result = isnull(mapA) && isnull(mapT) || mapA == mapT
-> result = isnull(null) && isnull(null) || null == null
-> result = 1 && 1 || null
-> result = 1 || null
-> result = null
while Test2 reduces to:
result = isnull(mapA) && isnull(mapT) ||| mapA == mapT
-> result = isnull(null) && isnull(null) ||| null == null
-> result = 1 && 1 ||| null
-> result = 1 ||| null
-> result = 1
The || and && operators always propagate nulls (i.e. they return null
if either operand is null), while ||| and &&& return a non-null result
where possible (i.e. ||| returns 1 if either operand is non-zero, &&&
returns 0 if either operand is zero).
Thanks indeed for the enlightening. I am new to the mapcalc business and my obviously wrong (AWK-based) thinking was that mapcalc would do a lazy evaluation of the conditions, i.e. "1 && 1 || something" would always be 1, whatever "something" was. Now I know better.
Thanks again, Hermann
Glynn Clements wrote:
Hermann Peifer wrote:
I am trying to find out if 2 raster layers are exactly identical. I am not an experienced mapcalc user, so I am wondering, where the 3200204 NULL values come from, in Test1. The result in Test2 is what I expected.
My obviously wrong understanding was that I wouldn't need the special operator ||| in Test1, as NULL values are already treated specially by isnull()
If mapA and mapT are both null, then Test 1 reduces to:
result = isnull(mapA) && isnull(mapT) || mapA == mapT
-> result = isnull(null) && isnull(null) || null == null
-> result = 1 && 1 || null
-> result = 1 || null
-> result = null
while Test2 reduces to:
result = isnull(mapA) && isnull(mapT) ||| mapA == mapT
-> result = isnull(null) && isnull(null) ||| null == null
-> result = 1 && 1 ||| null
-> result = 1 ||| null
-> result = 1
The || and && operators always propagate nulls (i.e. they return null
if either operand is null), while ||| and &&& return a non-null result
where possible (i.e. ||| returns 1 if either operand is non-zero, &&&
returns 0 if either operand is zero).
Thanks indeed for the enlightening. I am new to the mapcalc business and
my obviously wrong (AWK-based) thinking was that mapcalc would do a lazy
evaluation of the conditions, i.e. "1 && 1 || something" would always
be 1, whatever "something" was. Now I know better.
r.mapcalc never does "short-circuit" evaluation. This is true for if()
and ?: as well as &&,||,&&&,|||.
&& and || propagate nulls, while &&& and ||| return non-null where
possible. All four operators are symmetric, so e.g. "null() ||| 1" and
"1 ||| null()" both evaluate to 1.
Thanks indeed for the enlightening. I am new to the mapcalc business and my obviously wrong (AWK-based) thinking was that mapcalc would do a lazy evaluation of the conditions, i.e. "1 && 1 || something" would always be 1, whatever "something" was. Now I know better.
r.mapcalc never does "short-circuit" evaluation. This is true for if()
and ?: as well as &&,||,&&&,|||.
&& and || propagate nulls, while &&& and ||| return non-null where
possible. All four operators are symmetric, so e.g. "null() ||| 1" and
"1 ||| null()" both evaluate to 1.