Numeric Types and Type Conversions

## 9.2 Numeric Types and Type Conversions

- Integers
- Rationals
- Floating Point Numbers
- Bounded Real Numbers
- Type Conversions

ECLiPSe distinguishes four types of numbers: integers, rationals, floats and bounded reals.

### 9.2.1 Integers

The magnitude of integers is only limited by your available memory. However, integers that fit into the word size of your computer are represented more efficiently (this distinction is invisible to the user). Integers are written in decimal notation or in base notation, for example:

>     0  3  -5  1024  16'f3ae  0'a  15511210043330985984000000

Note that integer range is unlimited if ECLiPSe was compiled with bignum support. Otherwise, integers are restricted to that representable in a machine word, and max_integer flag of get_flag/2 returns the maximum integer value.

### 9.2.2 Rationals

Rational numbers implement the corresponding mathematical domain, i.e., ratios of two integers (numerator and denominator). ECLiPSe represents rationals in a canonical form where the greatest common divisor of numerator and denominator is 1 and the denominator is positive. Rational constants are written as numerator and denominator separated by an underscore, e.g.,

>     1_3  -30517578125_32768  0_1

Rational arithmetic is arbitrarily precise. When the global flag prefer_rationals is set, the system uses rational arithmetic wherever possible. In particular, dividing two integers then yields a precise rational rather than a float result.

Rationals are supported if ECLiPSe is compiled with bignum support. If rationals are not supported, a type error will be raised when a rational is required.

### 9.2.3 Floating Point Numbers

Floating point numbers conceptually correspond to the mathematical domain of real numbers, but are not precisely represented. Floats are written with decimal point and/or an exponent, e.g.,

>     0.0  3.141592653589793  6.02e23  -35e-12  -1.0Inf

ECLiPSe uses IEEE double precision floats with the following conventions:

- overflows always produce infinity results, never overflow exceptions.
- invalid operations always produce arithemtic exceptions, never NaNs.
- positive (0.0) and negative zero (-0.0) are distinct and do not unify.

### 9.2.4 Bounded Real Numbers

It is a well known problem that floating point arithmetic suffers from rounding errors. To provide safe arithmetic over the real numbers, ECLiPSe also implements bounded reals1. A bounded real consists of a pair of floating point numbers which constitute a safe lower and upper bound for the real number that is being represented. Bounded reals are written as two floating point numbers separated by two underscores, e.g.,

>     -0.001__0.001  3.141592653__3.141592654  1e308__1.0Inf

A bounded real is a representation for a real number that definitely lies somewhere between the two bounds, but the exact value cannot be determined 2. Bounded reals are usually not typed in by the user, they are normally the result of a computation or type coercion.

All computations with bounded reals give safe results, taking rounding errors into account. This is achieved by doing interval arithmetic on the bounds and rounding the results outwards. The resulting bounded real is then guaranteed to enclose the true real result.

Computations with floating point values result in uncertainties about the correct result. Bounded reals make this uncertainty explicit. A consequence of this is that sometimes it is conceptually not possible to decide whether two bounded reals are identical or not. This occurs when the bounds of the compared intervals overlap. In this case, the arithmetic comparisons leave a (ground) delayed goal behind which can then be inspected by the user to decide whether the match is considered close enough. The syntactical comparisons like =/2 and ==/2 treat bounded reals simply as a pair of bounds, and consider them equal when the bounds are equal.

### 9.2.5 Type Conversions

Note that numbers of different types never unify, e.g., 3, 3_1, 3.0 and 3.0__3.0 are all different. Use the arithmetic comparison predicates when you want to compare numeric values. When numbers of different types occur as arguments of an arithmetic operation or comparison, the types are first made equal by converting to the more general of the two types, i.e., the rightmost one in the sequence

> integer → rational → float → bounded real

The operation or comparison is then carried out with this type and the result is of this type as well, unless otherwise specified. Beware of the potential loss of precision in the rational → float conversion! Note that the system never does automatic conversions in the opposite direction. Such conversion must be programmed explicitly using the integer, rational, float and breal functions.

1
  We have chosen to use the term bounded real rather than interval in order to avoid confusion with interval variables as used in the interval arithmetic constraint solvers
2
  This is in contrast to a floating point number, which represents a real number which lies somewhere in the vicinity of the float