This chapter describes the multiple precision arithmetic which is
embedded in the PROFIL/BIAS distribution but currently not contained in it.
Contact `knueppel@tu-harburg.d400.de`

for details.

Because some subroutines in PROFIL are different when using the multiple precision arithmetic, the whole library must be rebuilt to work correctly. Every rebuild must start with a

dmake CLEAN

in the PROFIL subdirectory. To build the library without multiple precision arithmetic, use

dmakearchitecture

as described in the installation section of PROFIL. See section Common Installation Steps, for details.

If you want to use the multiple precision arithmetic, use

dmake LR=xarchitecture

On a RS/6000 architecture using gcc, the command would be

dmake LR=x ibmgcc

Before rebuilding PROFIL, the multiple precision arithmetic libraries must have been built. Change to the appropriate directory with

cd lr

After that, use

dmakearchitecture

as you have used it to build BIAS, e.g.

dmake ibmgcc

Note that using the multiple precision arithmetic in your programs requires an
additional include path as well as 2 additional libraries. The basic multiple
precision include files are contained in the subdirectory `lr`. This subdirectory
also contains the two new libraries `Lr` and `Li`. If you want to move your
include files and your libraries to a different place, see section Common Installation Steps
for further information and do not forget to move the include files and libraries from
the subdirectory `lr`, too.

- Changes in Interval Input/Output
- Long Real Numbers
- Long Intervals
- High Precision Operations
- Acknowledgements

`REAL`

numbers, the first denotes the lower and the latter the
upper bound. On output, the lower and upper bound are separated by a comma
and surrounded by square brackets. Because the interval bounds are treated
as floating point numbers, the conversion routine of the C library which uses
a rounding to nearest is used. Therefore, an interval that is read in as

0.1 0.1

does not contain the real value 0.1 but is a point interval whose bounds are equal to a floating point approximation of 0.1.

This is no longer true when using the multiple precision arithmetic. With the multiple precision arithmetic, the interval input and output routines use the multiple precision interval I/O routines, all bounds on input and output are correctly rounded and the input format is the same as the output format. Additionally, there are some nice improvements when using intervals with a small relative diameter. For example, the interval [12.345,12.346] can be typed as:

[12.345,12.346] 12.34[5,6] 1.234[5,6]E+1 [1.2345,1.2346]E+1 [1.2345E+1,1.2346E+1]

For intervals like [1.999,2.002] the special notation

1.99[9,12]

can be used, where the `1` in the upper bound denotes a carry to be added
to the least significant common digit.
Point intervals can be read as one number, e.g. `0.1` and `[0.1,0.1]`
are the same interval, both containing the real number 0.1.

The output format for intervals is controlled by the same commands used for
the multiple precision reals/intervals.
See section Long Real Numbers --- `LongReal.h` and section Long Intervals --- `LongInterval.h`, for details.

Due to the same reasons discussed above, the function `Hull`

cannot be used
to get an enclosure of a real constant, e.g. by `Hull(0.1)`.
This is because `Hull(0.1)` returns a point interval whose bounds are equal
to a floating point approximation of 0.1. If you need an enclosure of 0.1,
use either `DivBounds(1.0,10.0)` or `Enclosure("1.0")`.
The latter is using the multiple precision package, where the first is independent
of it.

`LONGREAL`

.
**Data Type:**`LONGREAL`

`variable`[(char *`string`[, INT`precision`])]- Defines a long real variable. If
`string`is present,`variable`is initialized with the decimal constant contained in the string and the initial precison the determined by the precision of the decimal string constant. If the optional parameter`precision`is present, it denotes the initial precision in decimal digits for`variable`. Example:LONGREAL

`a`("1.234", 20);Defines

`a`, initializes`a`with the decimal constant 1.234 and sets the current precision of`a`to 20 decimal digits.

The current working precision (i.e. the initial precision of new declared variables and the precision of any calculated results) is controlled by the following routines:

**Function:**`void SetDigits (INT`

`n`)- Sets the current working precision to approx.
`n`decimal digits.

**Function:**`void SetBaseDigits (INT`

`n`)- Sets the current working precision to
`n`base 65536 digits.

**Function:**`INT GetDigits ()`

- Returns the current working precision in approx.
`n`decimal digits.

**Function:**`INT GetBaseDigits ()`

- Returns the current working precision in
`n`base 65536 digits.

The basic operations `+`, `-`, `*`, and `/`, the unary operators
`+` and `-` as well as `+=`, `-=`, `*=`, and `/=` are
defined for long real numbers. The operand type `REAL`

is also allowed as long
as at least one operand is of type `LONGREAL`

.

The predecessor and successor of a long real expression can be obtained by `--`
and `++`.

Comparisons of long real numbers are possible with `==`, `!=`, `<`, `<=`,
`>`, and `>=`.

Additionally, the following functions are provided:

**Function:**`void MakeTemporary (LONGREAL`

`a`)- Defines
`a`to be a temporary variable. This is only important when the improved memory management is used.See section Vector Operations ---

`Vector.h`, function`MakeTemporary`

for more information.

**Function:**`void MakePermanent (LONGREAL`

`a`)- Changes the temporary variable
`a`into a permanent one.See section Configuration, for details.

**Function:**`REAL RoundToReal (LONGREAL`

`a`[, INT`rounding mode`])- Returns the value of
`a`rounded to a`REAL`

value. The following values are possible for`rounding mode`, where the rounding to nearest is the default:`LR_RND_NEAR`

- Rounds to the nearest
`REAL`

value. `LR_RND_DOWN`

- Rounds downwards to the next
`REAL`

value. `LR_RND_UP`

- Rounds upwards to the next
`REAL`

value.

**Function:**`void Accumulate (LONGREAL`

`a`, VECTOR`v`, VECTOR`w`)- Calculates the accurate scalar product of
`v`and`w`and adds it to`a`.**Important:**The precision of`a`is unchanged!

**Function:**`LONGREAL StringToLongReal (char *`

`s`)- Converts the decimal string constant
`s`to a long real number.

The input and output of long real numbers is written as for all other data types. Currently, long real numbers are always output using an exponential format. Only the number of digits and the output rounding mode can be controlled. The following functions are used to control the output format for long real numbers and for the long intervals described in the next section:

**Function:**`void SetOutFracDigits (INT`

`n`)- Sets the number of fractional digits on output to
`n`.

**Function:**`void SetOutIntDigits (INT`

`n`)- Sets the maxmium number of integer digits to
`n`. If the true number of integer digits is larger, the exponential format will be used.This function affects only the output of long intervals.

**Function:**`void SetOutRndMode (INT`

`n`)- Sets the output rounding mode for long real numbers.
Possible values for
`n`are:`0`

- Round to nearest.
`1`

- Round downwards.
`2`

- Round upwards.
`3`

- Round by chopping.

**Function:**`INT GetOutFracDigits ()`

- Returns the current number of fractional digits.

**Function:**`INT GetOutIntDigits ()`

- Returns the current number of integer digits.

**Function:**`INT GetOutRndMode ()`

- Returns the current output rounding mode.

`LONGINTERVAL`

.
**Data Type:**`LONGINTERVAL`

`variable`[(char *`string`[, INT`precision`])]- Defines a long interval variable. If
`string`is present,`variable`is initialized with the decimal constant interval contained in the string. If the optional parameter`precision`is present, it denotes the initial precision in decimal digits for`variable`. Example:LONGINTERVAL

`a`("[1.2,1.3]", 20);Defines

`a`, initialized`a`with the decimal constant interval [1.2,1.3] and sets the current precision of`a`to 20 decimal digits.

The basic operations `+`, `-`, `*`, and `/`, the unary operators
`+` and `-` as well as `+=`, `-=`, `*=`, and `/=` are
defined for long intervals. The operand types `REAL`

, `INTERVAL`

, and
`LONGREAL`

are also allowed as long as at least one operand is of type `LONGINTERVAL`

.

The current working precision is controlled by the same commands used for the long
real numbers.
See section Long Real Numbers --- `LongReal.h`, for details.

Additionally, the following functions are provided:

**Function:**`void MakeTemporary (LONGINTERVAL`

`a`)- Defines
`a`to be a temporary variable. This is only important when the improved memory management is used.See section Vector Operations ---

`Vector.h`, function`MakeTemporary`

for more information.

**Function:**`void MakePermanent (LONGINTERVAL`

`a`)- Changes the temporary variable
`a`into a permanent one.See section Configuration, for details.

**Function:**`LONGREAL Inf (LONGINTERVAL`

`a`)- Returns the lower bound of
`a`.

**Function:**`LONGREAL Sup (LONGINTERVAL`

`a`)- Returns the upper bound of
`a`.

**Function:**`LONGINTERVAL Hull (LONGREAL`

`a`)- Returns an enclosure of the long real number
`a`.See section Changes in Interval Input/Output, for more information about

`Hull`

.

**Function:**`LONGINTERVAL Hull (LONGREAL`

`a`, LONGREAL`b`)- Returns an enclosure of the convex hull of
`a`and`b`.

**Function:**`LONGREAL Diam (LONGINTERVAL`

`a`)- Returns the diameter of
`a`.

**Function:**`LONGREAL Mid (LONGINTERVAL`

`a`)- Returns the midpoint of
`a`.

**Function:**`INTERVAL RoundToInterval (LONGINTERVAL`

`a`)- Returns the value of
`a`rounded to the smallest enclosing`INTERVAL`

value.

**Function:**`void Accumulate (LONGINTERVAL`

`a`,`v`,`w`)- Calculates the accurate scalar product of the vectors
`v`and`w`(the types`VECTOR`

and`INTERVAL_VECTOR`

are possible either) and adds the result to`a`.**Important:**The precision of`a`is unchanged!

**Function:**`INTERVAL Enclosure (char *`

`s`)- Returns an interval which encloses the interval given by the decimal string
constant
`s`.

**Function:**`LONGINTERVAL LongIntervalEnclosure (char *`

`s`)- Same as
`Enclosure`

, but returns a long interval.

The output format of long intervals is controlled by the same commands used for the long real numbers. Additionally, the appearance of the output can be changed by the following command:

**Function:**`void SetOutOptions (INT`

`n`)- Defines the output format for long intervals. Allowed values for
`n`are:`LI_FSTR_INT`

- If the interval bounds are integer values and the number of decimal digits
is less than the value returned by
`GetIntDigits`

, the bounds are written to output without any fractional digits.Otherwise, the next format is tried.

`LI_FSTR_FRACCOM`

- If there are common leading digits for the interval bounds, they are
extracted and displayed only once. For example the interval [1.234,1.235]
is displayed as
`1.23[4,5]`.Otherwise, the next format is tried.

`LI_FSTR_FRACSEP`

- If the interval bounds are not too large (less than
`GetIntDigits`

integer digits), they are displayed as two floating point numbers.Otherwise, the exponential format is used.

If

`LI_STR_SINGLE`

is added to any of the above values, all spaces used for indentation are removed.The default output format is

(LI_FSTR_INT | LI_STR_SINGLE)

**Function:**`REAL HighPrecMul (VECTOR`

`v`, VECTOR`w`)- Returns the accurate scalar product of
`v`and`w`rounded to the nearest`REAL`

value.

**Function:**`VECTOR HighPrecMul (MATRIX`

`A`, VECTOR`w`)- Returns the accurate matrix-vector product of
`A`and`w`where every component of the result is rounded to the nearest`REAL`

value.

**Function:**`MATRIX HighPrecMul (MATRIX`

`A`, MATRIX`A`)- Returns the accurate matrix product of
`A`and`A`where every component of the result is rounded to the nearest`REAL`

value.

**Function:**`INTERVAL HighPrecMulBounds (VECTOR`

`v`, VECTOR`w`)- Returns an enclosure of the accurate scalar product of
`v`and`w`.

**Function:**`INTERVAL_VECTOR HighPrecMulBounds (MATRIX`

`A`, VECTOR`w`)- Returns an enclosure of the accurate matrix-vector product of
`A`and`w`.

**Function:**`INTERVAL_MATRIX HighPrecMulBounds (MATRIX`

`A`, MATRIX`B`)- Returns an enclosure of the accurate matrix product of
`A`and`B`.

**Function:**`INTERVAL HighPrecMul (`

`v`,`w`)- Returns an enclosure of the accurate scalar product of the
`v`and`w`. The parameters`v`and`w`may either be of type`VECTOR`

or`INTERVAL_VECTOR`

but not both`VECTOR`

.

**Function:**`INTERVAL_VECTOR HighPrecMul (`

`A`,`w`)- Returns an enclosure of the accurate matrix-vector product of
`A`and`w`. The parameter`v`may either be`MATRIX`

or`INTERVAL_MATRIX`

and the parameter`w`may either be`VECTOR`

or`INTERVAL_VECTOR`

.The type combination

`MATRIX`

and`VECTOR`

is not allowed.

**Function:**`INTERVAL_MATRIX HighPrecMul (`

`A`,`B`)- Returns an enclosure of the accurate matrix product of
`A`and`B`. The parameters`v`and`w`may either be of type`MATRIX`

or`INTERVAL_MATRIX`

but not both`MATRIX`

.

**Function:**`INTERVAL_MATRIX IdMinusHighPrecMul (`

`A`,`B`)- Returns an enclosure of the identity matrix minus the accurate matrix
product of
`A`and`B`. The parameters`v`and`w`may either be of type`MATRIX`

or`INTERVAL_MATRIX`

.

Thomas Simenec wrote the test matrices contained in the PROFIL/BIAS extension package. He frequently tested many nearly similar revisions of all packages and gave many helpful hints for the DOS and OS/2 versions.

Many thanks go to Dirk Husung, whose long real package is the basis of all multiple precision routines.