$a include=template_file
$n$lm
IMP Core Environment Standard
$b2$lm
Section 3: Mathematical Procedures
$a sectno=3; pageno=1
$a indent=0
$b2$v5$p
The procedures described in this section give the IMP programmer access to
a range of basic mathematical functions.
This range is not intended to be as complete as, for example, the FORTRAN
intrinsic library or one of the major mathematical libraries such as
NAGLIB.
Instead, it is hoped that the needs of the majority of portable applications
will be met here without placing an undue burden on the implementor.
$b2$v5$p
At present, this standard does not prescribe a level of accuracy which the
procedures described here must attain in order for an implementation to
conform to the standard. Implementors are instead referred to [CODY80]
for an indication
of the level of accuracy which can be obtained with some care in
implementation.
$b2$v5$p
In an ideal world, all mathematical functions would return results which
were precisely correct in all cases. In practice, the results of IMP
procedures are constrained to be of at most the precision of a %long %real
variable, which means that they will differ from the ideal in some measure
for almost all arguments. The accumulation of similar errors during the
passing of arguments and computation of results also adds to the overall
deviation from the ideal. The procedures here are described
for clarity in terms of the ideal: a floating-point system of infinite
precision and near-infinite range, and any mathematical relationships or
example results given should be interpreted under this model.
However, it should always be borne in mind
that, unless otherwise stated in the text, any procedure involving real
numbers either as arguments, intermediate values or results will be subject
to errors of precision for certain argument and result values.
$a indent=1
$b4$v5$l
3.1 %real to %integer Conversion
$a indent=0
$p For %real to %integer conversions,
there are two basic operations which are commonly performed.
Firstly, the most common is to
round a %real value to the nearest %integer value: this facility is provided by
the functions ROUND and INT. Secondly, the programmer may wish to truncate the
%real value: this operation is embodied in TRUNC and INTPT as described below.
$v5$p The reason for defining a pair of procedures for each of these operations
is to cater for the two common definitions of the terms "round" and "truncate":
the procedures ROUND and TRUNC are defined in the sense of the
national and international standards [BS6192, ISO7185]
for the programming language PASCAL, i.e$. with truncation being
towards zero. These functions are to be preferred for most programs as their
operation is easily understood textually, for example ROUND and TRUNC of
"-3.6" are "-4" and "-3" respectively. These procedures are referred to below as
the "textual" versions of the conversion functions.
$v5$p The procedures INT and INTPT are based on an alternative definition of
truncation used in certain mathematical contexts. Here, INTPT corresponds to
TRUNC except that any truncation required is guaranteed to make the number less
positive, i.e$. INTPT(X)<=X. This is in contrast to TRUNC's definition which
implies that TRUNC(X) will become closer to zero if X is not already integer.
Use of INT and INTPT is only recommended after careful consideration of a
program's requirements: the results from INTPT in particular can sometimes be
unexpected. For example, INTPT(-3.4)=-4 but INTPT(3.4)=3.
These procedures are most useful when some mathematical statement is to be made
about a program: their effect of modifying all numbers in the same direction on
the number line makes them easier to include in such statements.
INT and INTPT are referred to as the "monotonic" versions of the conversion
functions.
$v5$p In order to give the reader an overall idea of the intent of the
procedures defined formally in the two sub-sections which follow,
their effect on a range of key values are summarised in the following table.
Note that the effects on these key values are duplicated as examples in the
definitions of each individual procedure.
$b$v8$l0
'X' Int(X) Int Pt(X) Round(X) Trunc(X)
-11.7 -12 -12 -12 -11
-1.2 -1 -2 -1 -1
-0.5 0 -1 -1 0
0.5 1 0 1 0
1.2 1 1 1 1
11.7 12 11 12 11
$b0
$a indent=1
$b4$v10$l
3.1.1 Textual Versions
$B4$v5$t0 * $t %integer %function TRUNC ( %long %real X )$B0
$p This function converts the given %long %real value into an integer, with any
truncation being towards zero (compare with INTPT where the truncation is
towards minus infinity). It is identical to the TRUNC function defined in
[BS6192] section 6.6.6.3.
The TRUNC function obeys the following relationships:
$B$l2i
X-1 < TRUNC(X) <= X {if X >= 0}
X <= TRUNC(X) < X+1 {if X < 0}
$B$v6$l0i
Examples: TRUNC(-11.7) = -11
TRUNC( -1.2) = -1
TRUNC( -0.5) = 0
TRUNC( 0.5) = 0
TRUNC( 1.2) = 1
TRUNC( 11.7) = 11
$B0
$B It is an error (ERR0007; %integer range exceeded) if the value of TRUNC(X)
exceeds the implementation defined range for the %integer data type (DEF0005;
range of %integer variables).
$B4$v5$t0 * $t %integer %function ROUND ( %long %real X )$B0
$p This function returns the integer closest to a given %long %real value.
In the case where the value is exactly halfway between two integer values
the value furthest from zero will be returned. It is identical to the ROUND
function defined in [BS6192] section 6.6.6.3. The ROUND function obeys
the following relations:
$B$l2i
X-1/2 < ROUND(X) <= X+1/2 {if X >= 0}
X-1/2 <= ROUND(X) < X+1/2 {if X < 0}
$B It may also be defined in terms of the TRUNC function by means of the
following relationships:
$B$v5$l0i
ROUND(X) = TRUNC(X+1/2) {if X >= 0}
ROUND(X) = TRUNC(X-1/2) {if X < 0}
$B$v6$l0i
Examples: ROUND(-11.7) = -12
ROUND( -1.2) = -1
ROUND( -0.5) = -1
ROUND( 0.5) = 1
ROUND( 1.2) = 1
ROUND( 11.7) = 12
$b0
$B It is an error (ERR0007; %integer range exceeded) if the value of ROUND(X)
exceeds the implementation defined range for the %integer data type (DEF0005;
range of %integer variables).
$b4$v5$l
3.1.2 Monotonic Versions
$B4$v5$t0 * $t %integer %function INTPT ( %long %real X )$B0
$p This function converts the given %long %real value into an integer, with any
truncation being towards minus infinity (compare with TRUNC where the
truncation is towards zero).
The INTPT function obeys the following relation:
$B$li
X-1 < INTPT(X) <= X
$B$v6$l0i
Examples: INTPT(-11.7) = -12
INTPT( -1.2) = -2
INTPT( -0.5) = -1
INTPT( 0.5) = 0
INTPT( 1.2) = 1
INTPT( 11.7) = 11
$B0
$B It is an error (ERR0007; %integer range exceeded) if the value of INTPT(X)
exceeds the implementation defined range for the %integer data type (DEF0005;
range of %integer variables).
$B4$v5$t0 * $t %integer %function INT ( %long %real X )$B0
$p This function returns the integer closest to a given %long %real value.
In the case where the argument lies exactly halfway between two integer values
the more positive integer value will be returned. The INT function obeys
the following relation:
$B$li
X-1/2 < INT(X) <= X+1/2
$B Alternatively, INT may be related to INTPT as follows:
$B$v5$l0i
INT(X) = INTPT(X+1/2)
$B$v5$l0i
Examples: INT(-11.7) = -12
INT( -1.2) = -1
INT( -0.5) = 0
INT( 0.5) = 1
INT( 1.2) = 1
INT( 11.7) = 12
$B0
$B It is an error (ERR0007; %integer range exceeded) if the value of INT(X)
exceeds the implementation defined range for the %integer data type (DEF0005;
range of %integer variables).
$b4$v5$l
3.2 Trigonometric Functions
$p All angles are in radians. For SIN, COS and TAN, X is %not restricted to be
less than 2*PI.
$b4$v5$t0 * $t %constant %long %real PI
$p The value of the mathematical constant 'pi' expressed to the maximum accuracy
of a %long %real.
$b4$v5$t0 * $t %long %real %function SIN ( %long %real X ) $b0
$p Sine of X
$b4$v5$t0 * $t %long %real %function COS ( %long %real X ) $b0
$p Cosine of X
$b4$v5$t0 * $t %long %real %function TAN ( %long %real X ) $b0
$p Tangent of X
$b4$v5$t0 * $t %long %real %function ARC SIN ( %long %real X ) $b0
$p Arc Sine of X. It is an error unless |X| <= 1. The range of the
result is -PI/2 <= result <= PI/2.
$b4$v5$t0 * $t %long %real %function ARC COS ( %long %real X ) $b0
$p Arc Cosine of X. It is an error unless |X| <= 1. The range of the
result is 0 <= result <= PI.
$b4$v5$t0 * $t %long %real %function ARC TAN 1 ( %long %real X ) $b0
$p Arc Tangent of X.
Mathematically, the result range should be -PI/2$ <$ result$ <$ PI/2, but
the limited precision of machine arithmetic may cause the range to
increase to include the two end-points. This is because, at the limits of the
argument range (positive and negative numbers approaching the limits of the
machine's floating-point range) the mathematically correct result is
indistinguishable from +/-$ PI/2, and is in addition closer to +/-$ PI/2 than
it is to the machine representation of any other number within the exclusive
range.
In practice, then, the result range of ARC$ TAN is -PI/2$ <=$ result$ <=$ PI/2.
$b4$v5$t0 * $t %long %real %function ARC TAN ( %long %real X, Y ) $b0
$p Arctangent of (Y/X).
If Y is positive, the result is positive.
If Y is zero, the result is zero if X is positive and PI if X is negative.
If Y is negative, the result is negative.
If X is zero, the absolute value of the result is PI/2.
It is an error if X=Y=0.
The range of the result for ARC$ TAN is: -PI < result <= PI.
$b4$v5$l
3.3 Miscellaneous
$B4$v5$t0 * $t %long %real %function FRACTION ( %long %real X )$B0
$p This function returns the remainder after the parameter has been
converted to an %integer with truncation towards zero. It obeys the
following relation:
$B$l2i
FRACTION(X) = X-TRUNC(X)
so that X = TRUNC(X)+FRACTION(X)
$B$v6$l0i
Examples: FRACTION(-11.7) = -0.7
FRACTION( -1.2) = -0.2
FRACTION( -0.5) = -0.5
FRACTION( 0.5) = 0.5
FRACTION( 1.2) = 0.2
FRACTION( 11.7) = 0.7
$B0
$B4$v5$t0 * $t %long %real %function FRACPT ( %long %real X )$B0
$p This function returns the remainder after the parameter has been
converted to an %integer with truncation towards minus infinity. It obeys the
following relation:
$B$l2i
FRACPT(X) = X-INTPT(X)
so that X = INTPT(X)+FRACPT(X)
$B$v6$l0i
Examples: FRACPT(-11.7) = 0.3
FRACPT( -1.2) = 0.8
FRACPT( -0.5) = 0.5
FRACPT( 0.5) = 0.5
FRACPT( 1.2) = 0.2
FRACPT( 11.7) = 0.7
$B Note that, because of this definition, FRACPT(X) will always be positive.
$B4$v5$t0 * $t %long %real %function FLOAT ( %long %real X )$B0
$p This function simply returns its %long %real parameter as result.
Its principal use is in forcing calculations to be performed as real
where the compiler might otherwise perform them as integer and risk
an integer overflow condition.
$B$l0i
Example: %integer I, J ; %real R
I = 1000000 ; J = 1000000
R = I*J {may overflow}
can become R = FLOAT(I)*FLOAT(J) {usually larger range}
$B0
$B$v5 FLOAT may also be used to ensure that a particularly critical
computation is performed at the higher level of precision offered by
%long %real values.
$B$l0i
Example: %real R, A, B, C
A = 1@10 ; B = 1@10 ; C = 1
Example: R = (A+C)-B {may lose precision}
can become R = (FLOAT(A)+C)-FLOAT(B) {usually more precision}
$B0
$b4$v5$t0 * $t %integer %function REM ( %integer A, B )$b0
$p This function gives the remainder after A is divided by B in integer
arithmetic.
It obeys the following relation:
$b$v5$l
REM(A, B) = A - TRUNC(A/B) * B
$b This may alternatively be specified using IMP %integer arithmetic as
follows:
$b$v5$l
REM(A, B) = A - A//B * B
$b It can be shown that
the sign of the result is the same as the sign of the dividend (A).
It is an error (ERR0002; Division by zero) if B is zero.
$b$v5$l0i
Examples: REM(10,10) = 0
REM(10,3) = 1
REM(10,-3) = 1
REM(-10,3) = -1
$b0
$b4$v5$t0 * $t %integer %function MUL DIV ( %integer A, B, C )$b0
$p {informal & provisional}
Result is ROUND(A*B/C) to infinite precision and range.
$b4$v5$t0 * $t %long %real %function LOG ( %long %real X ) $b0
$p {informal & provisional}
Natural Logarithm of X; Log[base e](X). Error if (X<=0).
$b4$v5$t0 * $t %long %real %function EXP ( %long %real X ) $b0
$p {informal & provisional}
Exponential function; e^X.
$b4$v5$t0 * $t %long %real %function SQRT ( %long %real X ) $b0
$p {informal & provisional}
Square root; X^(1/2). Error if (X<0).