# BASIC subroutines

The BASIC subroutines are the recommended method of using
AccuMath in your applications. They isolate the programmer from calling
the Assembler subroutines (user-exits), and provide the greatest degree
of portability and functionality.

The BASIC subroutines include all of the functions supported
by BASIC. These are +, -, *, /, ABS, COS, EXP, INT, LN, PWR, SIN, SQRT, and TAN. Two other functions that
are not found in BASIC are CMP, used to compare
two high precision numbers, and PRC, used to set
the precision of an argument.

When using the BASIC subroutines,
it is important to remember to use distinct variables (or expressions
or constants) for each of the arguments passed or returned by the
subroutine. Many implementations of BASIC give incorrect results when
a variable is used for more than one argument in a subroutine. *Never* code a subroutine call like this:

```
CALL XADD(TOTAL,AMOUNT,TOTAL) incorrect usage!
```
In the above example, the variable TOTAL is passed to the subroutine in two places in the argument list.
Instead, code the call like this:

```
TEMP=TOTAL
CALL XADD(TEMP,AMOUNT,TOTAL) correct usage
```

## Addition

Two arguments may be added together
using the XADD or XADDX subroutine.
For XADD (or XADDX when PRECISION is null), the precision of the result will be
the greater of the precision of either of the arguments. For XADDX with PRECISION not null, the result
will be rounded to the specified precision.

```
CALL XADD(ARG1,ARG2,RESULT)
CALL XADDX(ARG1,ARG2,PRECISION,RESULT)
```

## Subtraction

The difference between two arguments
(ARG1 - ARG2) may be computed
using the XSUB or XSUBX subroutine.
For XSUB (or XSUBX when PRECISION is null), the precision of the result will be
the greater of the precision of either of the arguments. For XSUBX with PRECISION not null, the result
will be rounded to the specified precision.

```
CALL XSUB(ARG1,ARG2,RESULT)
CALL XSUBX(ARG1,ARG2,PRECISION,RESULT)
```

## Multiplication

The product of two arguments
may be computed using the XMUL or XMULX subroutine. For XMUL, the precision of the result
will be the greater of the precision of either of the arguments; that
is, the product will be rounded to the precision of the source argument
with the greatest precision. For example, if `ARG1=2.494` (precision=3) and ARG2=1.23 (precision=2) then RESULT=3.068 (precision=3) which is 3.06762 rounded to
precision 3. For XMULX with PRECISION is null, the precision of the result will be sum of the precision
of each of the arguments. For example, if ARG1=1.25 (precision=2)
and ARG2=0.375 (precision=3), then RESULT=0.46875 (precision=5). For XMULX when PRECISION not null, the product will be rounded to the specified precision.

```
CALL XMUL(ARG1,ARG2,RESULT)
CALL XMULX(ARG1,ARG2,PRECISION,RESULT)
```

## Division

The quotient of two arguments (ARG1 / ARG2) may be computed using the XDIV or XDIVX subroutine. For XDIV, the precision of the result will be the greater of the precision
of either of the arguments. The least significant digit of the quotient
will be rounded correctly. For XDIVX when PRECISION is not null, the result will be rounded to the
specified precision. For XDIVX when PRECISION is null, the precision of the result will be the default precision
(standard default is 14).

```
CALL XDIV(ARG1,ARG2,RESULT)
CALL XDIVX(ARG1,ARG2,PRECISION,RESULT)
```

## Absolute Value

The XABS or XABSX subroutine returns the absolute numeric
value of the argument. An absolute value is the numerical value of
a number without reference to its algebraic sign. While the result
looks positive it is actually unsigned. The precision of the result
is the precision of argument. For XABSX, PRECISION is ignored.

```
CALL XABS(ARG1,RESULT)
CALL XABSX(ARG1,PRECISION,RESULT)
```

## Cosine of an Angle

The XCOS or XCOSX subroutine is used to generate the cosine
of an angle expressed in degrees. For XCOS, the
precision of the result is the precision of the argument. For XCOSX when PRECISION is not null, the
result will be rounded to the specified precision. For XCOSX when PRECISION is null, the precision of the
result will be the default precision (standard default is 14).

The result will contain no more than 48 significant digits.

## Exponential

The XEXP or XEXPX subroutine may be used to raise the natural logarithm
base, e (2.71828...), to a power. For XEXP, the
precision of the result is the precision of the argument. For XEXPX when PRECISION is not null, the
result will be rounded to the specified precision. For XEXPX when PRECISION is null, the precision of the
result will be the default precision (standard default is 14).

The result will contain no more than 48 significant digits.

```
CALL XEXP(ARG1,RESULT)
CALL XEXPX(ARG1,PRECISION,RESULT)
```

## Integer Numeric Value

The XINT or XINTX subroutine is used to return the integer
portion of the specified expression. The fractional portion of the
argument is truncated. For XINTX, PRECISION is ignored.

```
CALL XINT(ARG1,RESULT)
CALL XINTX(ARG1,ARG2,RESULT)
```

## Natural Logarithm

The XLN or XLNX subroutine generates the natural (base
e) logarithm of the argument. The LN function
is the inverse of the EXP function. For XLN, the precision of the result is the precision of the
argument. For XLNX when PRECISION is not null, the result will be rounded to the specified precision.
For XLNX when PRECISION is null,
the precision of the result will be the default precision (standard
default is 14).

The result will contain no more than 48 significant
digits.

```
CALL XLN(ARG1,RESULT)
CALL XLNX(ARG1,PRECISION,RESULT)
```

## Raising by a Power

The XPWR or XPWRX subroutine raises the first argument
to the power specified in the second argument. If the second argument
is zero, the function will return the value one. For XPWR, the precision of the result will be the greater of the precision
of either of the arguments. For XPWRX when PRECISION is not null, the result will be rounded to the
specified precision. For XPWRX when PRECISION is null, the precision of the result will be the default precision
(standard default is 14).

The result will contain no more than
48 significant digits.

```
CALL XPWR(ARG1,ARG2,RESULT)
CALL XPWRX(ARG1,ARG2,PRECISION,RESULT)
```

## Sine of an Angle

The XSIN or XSINX subroutine is used to generate the sine
of an angle expressed in degrees. For XSIN, the
precision of the result is the precision of the argument. For XSINX when PRECISION is not null, the
result will be rounded to the specified precision. For XSINX when PRECISION is null, the precision of the
result will be the default precision (standard default is 14).

The result will contain no more than 48 significant digits.

```
CALL XSIN(ARG1,RESULT)
CALL XSINX(ARG1,PRECISION,RESULT)
```

## Square Root

The XSQRT or XSQRTX subroutine will return the positive
square root of any positive number. For XSQRT,
the precision of the result is the precision of the argument. For XSQRTX when PRECISION is not null, the
result will be rounded to the specified precision. For XSQRTX when PRECISION is null, the precision of the
result will be the default precision (standard default is 14).

The result will contain no more than 48 significant digits.

```
CALL XSQRT(ARG1,RESULT)
CALL XSQRTX(ARG1,PRECISION,RESULT)
```

## Tangent of an Angle

The XTAN or XTANX subroutine is used to generate the tangent
of an angle expressed in degrees. For XTAN, the
precision of the result is the precision of the argument. For XTANX when PRECISION is not null, the
result will be rounded to the specified precision. For XTANX when PRECISION is null, the precision of the
result will be the default precision (standard default is 14).

The result will contain no more than 48 significant digits.

```
CALL XTAN(ARG1,RESULT)
CALL XTANX(ARG1,PRECISION,RESULT)
```

## Comparison

Two arguments may be compared,
and the results (lower, equal, higher) determined. If the first argument
is less than the second argument then -1 is returned. If the first
argument is greater than the second argument then 1 is returned. If
the first argument is equal to the second argument then 0 is returned.
For XCMPX, PRECISION is ignored.

```
CALL XCMP(ARG1,ARG2,RESULT)
CALL XCMPX(ARG1,ARG2,PRECISION,RESULT)
```

## Precision

The precision of a value may be
set using the XPRC or XPRCX subroutine.
The first argument contains the value whose precision is being changed,
and the second argument contains the desired precision. The precision
must be a non-negative integer less than 32000.

If the precision
of the first argument is greater than the second argument, then the
first argument is rounded to precision specified by the second argument.
If the precision of the first argument is less than the second argument,
then trailing zeros (and possibly a decimal point) are added to the
end of the first argument forcing it to precision specified by the
second argument.

XPRC and XPRCX are identical. Both routines are included only for symmetry.

```
CALL XPRC(ARG1,ARG2,RESULT)
CALL XPRCX(ARG1,ARG2,RESULT)
```

---
Source: https://d3codex.com/accumath/basic-subroutines/ - part of the D3Codex reference.
