# Assembler subroutines

The Assembler subroutines are another method of using AccuMath
in your applications. The main advantage of using the Assembler
subroutines is that they are faster than the BASIC subroutines,
mainly due to the overhead of the BASIC CALL
statement. The main disadvantages of using the Assembler
subroutines are that they require the programmer to call the
Assembler subroutines using user-exits, and they only provide the
primary arithmetic operations: add, subtract, multiply, divide,
compare and precision. If execution speed is a priority however,
the Assembler subroutines are an acceptable method.

All of the Assembler subroutines (except XPRC)
have two modes, implicit precision and explicit precision. Their
operation is exactly as described in the preceding section (BASIC
subroutines).

When calling the Assembler subroutines, the following statement
should be included near the beginning of the program:

```
INCLUDE XP XPA.DEFS
```
Each of the Assembler subroutines is defined in the XPA.DEFS
item, and may then be referred to by a symbolic name.

The Assembler subroutines are called by using the BASIC
OCONV
function. The arguments are concatenated together (using attribute
marks to separate them), and passed as data to be converted. The
AccuMath function is used as the conversion code.

The following sections describe the Assembler subroutines in
more detail.

## Addition

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

```
RESULT = OCONV(ARG1:AM:ARG2,XADD)
RESULT = OCONV(ARG1:AM:ARG2:AM:PRECISION,XADDX)
```

## Subtraction

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

```
RESULT = OCONV(ARG1:AM:ARG2,XSUB)
RESULT = OCONV(ARG1:AM:ARG2:AM:PRECISION,XSUBX)
```

## 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
when PRECISION
is omitted, 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.

```
RESULT = OCONV(ARG1:AM:ARG2,XMUL)
RESULT = OCONV(ARG1:AM:ARG2:AM:PRECISION,XMULX)
```

## 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 omitted, the precision of the result will be the default
precision (standard default is 14).

```
RESULT = OCONV(ARG1:AM:ARG2,XDIV)
RESULT = OCONV(ARG1:AM:ARG2:AM:PRECISION,XDIVX)
```

## 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.

```
RESULT = OCONV(ARG1:AM:ARG2,XCMP)
RESULT = OCONV(ARG1:AM:ARG2:AM:PRECISION,XCMPX)
```

## Precision

The precision of a value may be set using the XPRC
 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.

```
RESULT = OCONV(ARG1:AM:ARG2,XPRC)
```

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