2 THE VAL_ FUNCTIONS

 2.1 Applicability & Efficiency
 2.2 VAL_ Error Handling
 2.3 VAL_ Arithmetic and Mathematical Functions
 2.4 VAL_ Type Conversion Functions
 2.5 Declaring the VAL_ Functions

The VAL_ functions are a set of Fortran functions which perform arithmetic, mathematical operations and type conversion on single (scalar) values stored using any numerical data type. These functions will handle numerical errors which occur during their evaluation (such as division by zero or overflow) and can also recognise and propagate the standard Starlink bad values.

They are normally invoked by statements of the form:

  RESULT = VAL_<name>( BAD, ARG, STATUS )

or

  RESULT = VAL_<name>( BAD, ARG1, ARG2, STATUS )

where <name > specifies the operation to be performed and:

2.1 Applicability & Efficiency

The VAL_ functions are designed primarily for ease of use and robustness, with efficiency being a secondary consideration. In fact, the overhead involved in invoking many of these functions exceeds the time required to actually perform the calculation. Consequently, VAL_ functions should not be used for processing large arrays of data. Rather, they are best used for relatively small numbers of calculations (up to a few thousand), when they can enhance the robustness and flexibility of applications by handling numerical errors and bad values with the minimum of programming effort.

The VEC_ routines (section 3) should normally be used for processing larger arrays of data.

2.2 VAL_ Error Handling

The error handling strategy used by the VAL_ routines consists of returning a bad function result under the following circumstances:

(1)
If STATUS is not set to SAI__OK when the function is invoked.
(2)
If the BAD argument is set to .TRUE. and any of the input arguments is bad.
(3)
If any numerical error occurs during evaluation of the function — in this latter case an appropriate error code will also be returned via the STATUS argument.

2.3 VAL_ Arithmetic and Mathematical Functions

Arithmetic and mathematical operations may be performed on scalar values stored using any numerical data type by invoking appropriate VAL_ functions, using statements such as:

  RESULT = VAL_<FUNC><T>( BAD, ARG, STATUS )

or

  RESULT = VAL_<FUNC><T>( BAD, ARG1, ARG2, STATUS )

Here, the VAL_ function takes an argument (or arguments) of type <T > and returns a result which is also of type <T >, having performed the arithmetic or mathematical operation specified by <FUNC >. The data type code <T > may be any of those specified in Table 1 and <FUNC > may be any of the function codes specified in Tables 2 & 3. The number of input arguments (1 or 2) appropriate to each function is also indicated in these latter Tables.





Function Code
<FUNC >
Number of
Arguments
Operation performed



ADD 2 addition: ARG1 + ARG2
SUB 2 subtraction: ARG1 ARG2
MUL 2 multiplication: ARG1 ARG2
DIV 2 *(floating) division: ARG1 / ARG2
IDV 2 **(integer) division: ARG1 / ARG2
PWR 2 raise to power: ARG1 ARG2
NEG 1 negate (change sign): ARG
SQRT 1 square root: ARG
LOG 1 natural logarithm: ln(ARG)
LG10 1 common logarithm: log 10(ARG)
EXP 1 exponential: exp(ARG)
ABS 1 absolute (positive) value: ARG
NINT 1 nearest integer value to ARG
INT 1 Fortran AINT (truncation to integer) function
MAX 2 maximum: max(ARG1, ARG2)
MIN 2 minimum: min(ARG1, ARG2)
DIM 2 Fortran DIM (positive difference) function
MOD 2 Fortran MOD (remainder) function
SIGN 2 Fortran SIGN (transfer of sign) function



Notes:
*Equivalent to NINT(REAL(ARG1)/REAL(ARG2)) for non-floating quantities
**Equivalent to AINT(ARG1/ARG2) for floating quantities




Table 2: Function codes used in routine names and the operations to which they correspond. The functions shown here are implemented for all the numerical data types (type codes UB, B, UW, W, I, R & D).

Thus, for example, the function VAL_ADDUW adds two unsigned word arguments to produce an unsigned word result, while VAL_SQRTD evaluates the square root of a double precision argument, returning a double precision result.

2.4 VAL_ Type Conversion Functions

Conversion of scalar values between numerical data types may be performed by invoking the appropriate VAL_ type conversion functions, using statements such as:

  RESULT = VAL_<T1>TO<T2>( BAD, ARG, STATUS )

Here, the VAL_ function takes an argument of type <T1 > and returns a result of type <T2 >, having performed type conversion. The data type codes <T1 > and <T2 > may be any of those specified in Table 1.

Thus, for example, the function VAL_BTOUW converts a byte argument to an unsigned word result, while VAL_DTOI converts from double precision to integer.

Note that conversions from floating point types (_REAL or _DOUBLE) to non-floating point types result in rounding of the data (not truncation as would happen with a Fortran assignment statement).





Function Code
<FUNC >
Number of
Arguments
Operation performed



SIN 1 *sine function: sin(ARG)
SIND 1 **sine function: sin(ARG)
COS 1 *cosine function: cos(ARG)
COSD 1 **cosine function: cos(ARG)
TAN 1 *tangent function: tan(ARG)
TAND 1 **tangent function: tan(ARG)
ASIN 1 *inverse sine function: sin 1(ARG)
ASND 1 **inverse sine function: sin 1(ARG)
ACOS 1 *inverse cosine function: cos 1(ARG)
ACSD 1 **inverse cosine function: cos 1(ARG)
ATAN 1 *inverse tangent function: tan 1(ARG)
ATND 1 *inverse tangent function: tan 1(ARG)
ATN2 2 *Fortran ATAN2 (inverse tangent) function
AT2D 2 **VAX Fortran ATAN2D (inverse tangent) function
SINH 1 hyperbolic sine function: sinh(ARG)
COSH 1 hyperbolic cosine function: cosh(ARG)
TANH 1 hyperbolic tangent function: tanh(ARG)



Notes:
*Argument(s)/result in radians
**Argument(s)/result in degrees




Table 3: Function codes used in routine names and the operations to which they correspond. The functions shown here are only implemented for the floating point data types (type codes R & D).

2.5 Declaring the VAL_ Functions

Since the VAL_ functions return a result via the routine name, appropriate declarations of their Fortran type must be made before they are used. Thus, for instance, an application which used the routines VAL_ADDUB and VAL_DTOI would require the declarations:

  BYTE VAL_ADDUB
  INTEGER VAL_DTOI

A routine suitable for processing by the GENERIC compiler might require equivalent generic declarations:

  <TYPE> VAL_ADD<T>
  <TYPE> VAL_DTO<T>