In section 2.7, it was observed that CARDINAL and INTEGER are assignment compatible, even if they are not expression compatible. Assignment compatibility is in this case a small concession to the normally strict rule against mixing types--these two are used in similar ways. It can be achieved easily because most computers also store values of these two types in similar ways. However, both the use and the storage of REAL values is quite different than for either INTEGER or CARDINAL values. Therefore one cannot in Modula-2 write either of

firstReal := -7; secondReal := firstReal + card;

where *firstReal* and *secondReal* are REAL and *card* is CARDINAL. That is:

In Modula-2 the type REAL is neither assignment compatible nor expression compatible with CARDINAL or INTEGER.

However, there is a way to convert numbers to and from REAL representation. If *re* is of type REAL and *ordnum* is of type INTEGER or CARDINAL, then

re :=FLOAT(ordnum)

will safely convert *ordnum* to a REAL, and assign the resulting value to *re*. Likewise,

card :=TRUNC(re)

will safely convert the whole number part of *re* to a CARDINAL and assign the resulting value to the variable *card*. Furthermore,

ordnum :=INT(re)

will safely convert the whole number part of *re* to an INTEGER and assign the resulting value to the variable *ordnum*.

**NOTES**: 1. These two are examples of what are called functions, or, more properly in Modula-2 function procedures.

2. The above definitions hold for ISO standard Modula-2. In some older implementations of Modula-2 the FLOAT may only work on one of the types INTEGER or CARDINAL and TRUNC conversions may produce an INTEGER rather than a CARDINAL. There may not even be an INT function procedure.

3. These two operations allow the creation of mixed expressions. Naturally, FLOAT and TRUNC have the precedence of parentheses.

4. TRUNC does not round off to the nearest cardinal, it "hacks off" the decimal part instead.

Assume *re* is REAL, *int* is INTEGER, and *card* is CARDINAL

re := 2.6 +FLOAT(5); Answer: 7.6 int := 26 - 2 *INT(re); Answer: 12 card := 26 -TRUNC(re * 2); Answer: 11 int :=INT(-4.75) - 6; Answer: -10

Many computers have more than one format for storing real numbers. Typically, there is one for reals with a somewhat limited range of significant figures and exponent, and one or more additional types with a greater range for both. Because of this, ISO standard Modula-2 provides for a second real type called LONGREAL. The precision and the exponent range for this type must be at least as great as for the type REAL. Thus, if only one real type is available in the underlying machine, the two real types would essentially be the same. However, since this is implementation defined (and somewhat exceptional), the compatibility rule is:

The Modula-2 type REAL and the Modula-2 type LONGREAL are not compatible.

Thus, besides the conversion functions above, ISO standard Modula-2 adds LFLOAT to convert to the type LONGREAL. Since REAL values need conversion to LONGREAL as well, LFLOAT takes any of CARDINAL, INTEGER, or REAL. In addition, INT, TRUNC, and FLOAT can take any numeric type that need to be converted to INTEGER, CARDINAL, or REAL, respectively. Note that this behaviour cannot be counted on in non-ISO standard versions.

Assume *int* is an INTEGER, *card* is a CARDINAL, *re* is a REAL and *lre* is a LONGREAL.

int :=INT(-3.5); Answer: -3 (works likeTRUNC) lre :=LFLOAT(2.7); Answer: 2.7 (* but stored as aLONGREAL*) lre :=LFLOAT(-3); Answer: -3.0 (* stored as aLONGREAL*) re :=FLOAT(-3); Answer: -3.0 (* stored as aREAL*) re :=FLOAT(INT(5.1)); Answer: 5.0 card :=TRUNC(-3.5); Answer: error; presumably need to useINTint :=INT(lre); Answer: be careful; could overflow!

**NOTES**: 1. Nonstandard versions that add such types as LONGINT and LONGCARD may have additional conversion functions.

2. Many nonstandard versions add the conversion function CARD, to convert to CARDINAL, instead of or in addition to TRUNC.

3. In the ISO standard, TRUNC, INT, FLOAT, and LFLOAT are simply short notation for the corresponding use of VAL (mentioned briefly in section 2.7). That is,

INT (r) means VAL (INTEGER, r),

TRUNC (r) means VAL (CARDINAL, r),

FLOAT (i) means VAL (REAL, i), and

LFLOAT (i) means VAL (LONGREAL, i).

The Modula-2 function procedure VAL(newType,item) safely converts the value stored in item into a corresponding value of the type newType.