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:
or
where name specifies the operation to be performed and:
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.
The error handling strategy used by the VAL_ routines consists of returning a bad function result under the following circumstances:
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:
or
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.
|
| 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: | ||||
LOG | 1 | natural logarithm: | ||||
LG10 | 1 | common logarithm: | ||||
EXP | 1 | exponential: | ||||
ABS | 1 | absolute (positive) value: | ||||
NINT | 1 | nearest integer value to ARG | ||||
INT | 1 | Fortran AINT (truncation to integer) function | ||||
MAX | 2 | maximum: | ||||
MIN | 2 | minimum: | ||||
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(ARG1ARG2) for floating quantities
| ||||||
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.
Conversion of scalar values between numerical data types may be performed by invoking the appropriate VAL_ type conversion functions, using statements such as:
Here, the VAL_ function takes an argument of type T and returns a result of type T, having performed type conversion. The data type codes T and T 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).
|
| Operation performed | ||||
SIN | 1 | *sine function: | ||||
SIND | 1 | **sine function: | ||||
COS | 1 | *cosine function: | ||||
COSD | 1 | **cosine function: | ||||
TAN | 1 | *tangent function: | ||||
TAND | 1 | **tangent function: | ||||
ASIN | 1 | *inverse sine function: | ||||
ASND | 1 | **inverse sine function: | ||||
ACOS | 1 | *inverse cosine function: | ||||
ACSD | 1 | **inverse cosine function: | ||||
ATAN | 1 | *inverse tangent function: | ||||
ATND | 1 | *inverse tangent function: | ||||
ATN2 | 2 | *Fortran ATAN2 (inverse tangent) function | ||||
AT2D | 2 | **VAX Fortran ATAN2D (inverse tangent) function | ||||
SINH | 1 | hyperbolic sine function: | ||||
COSH | 1 | hyperbolic cosine function: | ||||
TANH | 1 | hyperbolic tangent function: | ||||
Notes: | *Argument(s)/result in radians
| |||||
**Argument(s)/result in degrees
| ||||||
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:
A routine suitable for processing by the GENERIC compiler might require equivalent generic declarations: