# Ulm's Oberon Library: Reals

## NAME

Reals - conversions from/to real numbers

## SYNOPSIS

```CONST maxexp = 309;
CONST minexp = -323;
CONST maxdignum = 16;
CONST maxlongexp = 4932;
CONST minlongexp = -4951;
CONST maxlongdignum = 19;

PROCEDURE ExpAndMan(r: LONGREAL; long: BOOLEAN; base: INTEGER;
VAR exponent: INTEGER; VAR mantissa: LONGREAL);
PROCEDURE Power(base: LONGREAL; exp: INTEGER) : LONGREAL;
PROCEDURE Digits(mantissa: LONGREAL; base: INTEGER;
VAR buf: ARRAY OF CHAR;
VAR neg: BOOLEAN;
force: BOOLEAN; VAR ndigits: INTEGER);
PROCEDURE Convert(digits: ARRAY OF CHAR; base: INTEGER; neg: BOOLEAN;
VAR mantissa: LONGREAL);
```

## DESCRIPTION

Reals offers some base routines for converting from and to real numbers. Valid base values are 2, 8, 10, and 16.

Some constants are exported for real numbers of type REAL and LONGREAL:

maxexp
maximal exponent of REAL numbers
minexp
minimal exponent of REAL numbers
maxdignum
maximal number of significant digits in decimal representation
maxlongexp
maximal exponent of LONGREAL numbers
minlongexp
minimal exponent of LONGREAL numbers
maxlongdignum
maximal number of significant digits in decimal representation

ExpAndMan divides r into exponent and mantissa according to following rules:

(1)
(1.0 <= ABS(mantissa)) & (ABS(mantissa) < base)
(2)
r = mantissa * base^exponent

long should be FALSE if a REAL-value is passed to r.

Digits converts mantissa into a sequence of digits ("0" to "9" and "A" to "F" (if base = 16)). mantissa must hold (1) of ExpAndMan. In normal case (ndigits = 0) all significant digits are generated into buf. If ndigits is positive it specifies the number of digits to be stored into buf. ndigits is diminished to the number of significant digits if force is FALSE. Trailing zeroes are cut and the actual number of digits stored into buf is returned in ndigits. buf is guaranteed to be 0X-terminated. neg is set to TRUE if mantissa is negative.

Convert converts normalized digits (implicit decimal point after first digit) into mantissa.

Power returns base^exp.

## EXAMPLE

Following procedure writes a REAL-number in exponential format:
```PROCEDURE WriteReal(r: REAL);
CONST
base = 10;
VAR
exponent: INTEGER;
mantissa: LONGREAL;
digits: ARRAY Reals.maxdignum+1 OF CHAR;
ndigits: INTEGER;
neg: BOOLEAN;
index: INTEGER;
BEGIN
Reals.ExpAndMan(r, (* long = *) FALSE, base, exponent, mantissa);
ndigits := 0; (* all significant digits *)
Reals.Digits(mantissa, base, digits, neg,
(* force = *) FALSE, ndigits);
IF neg THEN
Write.Char("-");
END;
Write.Char(digits[0]);
IF ndigits > 1 THEN
Write.Char(".");
index := 1;
WHILE index < ndigits DO
Write.Char(digits[index]);
INC(index);
END;
END;
Write.Char("E"); Write.Int(exponent, 0);
END WriteReal;
```