Next: , Previous: Syntax of ncap2 statements, Up: ncap2 netCDF Arithmetic Processor


4.1.2 Expressions

Expressions are the fundamental building block of ncap2. Expressions are composed of variables, numbers, literals, and attributes. The following C operators are “overloaded” and work with scalars and multi-dimensional arrays:

     Arithmetic Operators: * / % + - ^
     Binary Operators:     > >= < <= == != == || && >> <<
     Unary Operators:      + - ++ -- !
     Conditional Operator: exp1 ? exp2 : exp3
     Assign Operators:     = += -= /= *=

In the following section a variable also refers to a number literal which is read in as a scalar variable:

Arithmetic and Binary Operators

Consider var1 'op' var2

Precision

Rank

Even though the logical operators return True(1) or False(0) they are treated in the same way as the arithmetic operators with regard to precision and rank.

examples:

     dimensions: time=10, lat=2, lon=4
     Suppose we have the two variables:
     
     double  P(time,lat,lon);
     float   PZ0(lon,lat);  // PZ0=1,2,3,4,5,6,7,8;
     
     Consider now the expression:
      PZ=P-PZ0
     
     PZ0 is made to conform to P and the result is
     PZ0 =
        1,3,5,7,2,4,6,8,
        1,3,5,7,2,4,6,8,
        1,3,5,7,2,4,6,8,
        1,3,5,7,2,4,6,8,
        1,3,5,7,2,4,6,8,
        1,3,5,7,2,4,6,8,
        1,3,5,7,2,4,6,8,
        1,3,5,7,2,4,6,8,
        1,3,5,7,2,4,6,8,
        1,3,5,7,2,4,6,8,
     
     Once the expression is evaluated then PZ will be of type double;
     
     Consider now
      start=four-att_var@double_att;  // start =-69  and is of type intger;
      four_pow=four^3.0f               // four_pow=64 and is of type float
      three_nw=three_dmn_var_sht*1.0f; // type is now float
      start@n1=att_var@short_att*att_var@int_att;
                                       // start@n1=5329 and is type int

Binary Operators
Unlike C the binary operators return an array of values. There is no such thing as short circuiting with the AND/OR operators. Missing values are carried into the result in the same way they are with the arithmetic operators. When an expression is evaluated in an if() the missing values are treated as true.
The Binary operators are,in order of precedence:

     
     !   Logical Not
     ----------------------------
     <<  Less Than Selection
     >>  Greater Than Selection
     ----------------------------
     >   Greater than
     >=  Greater than or equal to
     <   Less than
     <=  Less than or equal to
     ----------------------------
     ==  Equal to
     !=  Not equal to
     ----------------------------
     &&  Logical AND
     ----------------------------
     ||  Logical OR
     ----------------------------
     

To see all operators: see Operators precedence and associativity

examples:

     tm1= time>2 && time <7;  // tm1 = 0, 0, 1, 1, 1, 1, 0, 0, 0, 0 ; type double;
     tm2= time==3 || time>=6; // tm2 = 0, 0, 1, 0, 0, 1, 1, 1, 1, 1 ; type double
     tm3= int(!tm1);          // tm3=  1, 1, 0, 0, 0, 0, 1, 1, 1, 1 ; type int
     tm4= tm1 && tm2;         // tm4=  0, 0, 1, 0, 0, 1, 0, 0, 0, 0 ; type double;
     tm5= !tm4;               // tm5=  1, 1, 0, 1, 1, 0, 1, 1, 1, 1 ; type double;
     

Regular Assign Operator
var1 '=' exp1
If var1 doesn't already exist in Output then var1 is written to Output with the values and dimensions from expr1. If var1 already exists in Output, then the only requirement on expr1 is that the number of elements must match the number already on disk. The type of expr1 is converted if necessary to the disk type.

Other Assign Operators +=,-=,*=./=
var1 'ass_op' exp1
if exp1 is a variable and it doesn't conform to var1 then an attempt is made to make it conform to var1. If exp1 is an attribute it must have unity size or else have the same number of elements as var1. If expr1 has a different type to var1 the it is converted to the var1 type.

example:

     z1=four+=one*=10 // z1=14 four=14 one=10;
     time-=2          // time= -1,0,1,2,3,4,5,6,7,8

Increment/ Decrement Operators
These work in a similar fashion to their regular C counterparts. If say the variable "four" is input only then the statement "++four" effectively means -read four from input increment each element by one , then write the new values to Output;

example:

     n2=++four;   n2=5, four=5
     n3=one--+20; n3=21  one=0;
     n4=--time;   n4=time=0.,1.,2.,3.,4.,5.,6.,7.,8.,9.;

Conditional Operator ?:
exp1 ? exp2 : exp3
The conditional operator ( or ternary Operator) is nice and succinct way of writing an if/then/else. If exp1 evaluates to true then exp2 is returned else exp3 is returned.

example

     weight_avg= weight.avg();
     weight_avg@units= (weight_avg ==1 ? "kilo" : "kilos");
     
     PS_nw= PS - (PS.min() >100000 ? 100000 : 0 );

Clipping Operators

<< Less Than Selection
For arrays, the less-than selection operator selects all values in the left operand that are less than the corresponding value in the right operand. If the value of the left side is greater than or equal to the corresponding value of the right side, then the right side value is placed in the result
>> Greater Than Selection
For arrays, the greater-than selection operator selects all values in the left operand that are greater than the corresponding value in the right operand. If the value of the left side is less than or equal to the corresponding value of the right side, then the right side value is placed in the result.

example:

     
     RDM2= RDM >>100.0;   RDM2=100,100,100,100,126,126,100,100,100, 100 ;  // type double
     RDM2= RDM <<90s;     RDM3=1, 9, 36, 84, 90, 90, 84, 36, 9, 1 ;        // type int