Floating point arithmetic, as specified by [http://en.wikipedia.org/wiki/IEEE_floating_point IEEE 754], is available in almost every computer system today. It is wide-spread, implemented in common hardware and integral part in programming languages. For example, the
extended precision format is the default numeric data type in GNU Octave. Benefits are obvious: The results of arithmetic operations are well-defined and comparable between different systems and computation is highly efficient.
However, there are some downsides of floating point arithmetic in practice, which will eventually produce errors in computations.* Floating point arithmetic is often used mindlessly by developers. [http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html] [http://www.cs.berkeley.edu/~wkahan/Mindless.pdf]
* The binary data types categorically are not suitable for doing financial computations. Very often representational errors are introduced when using “real world” decimal numbers. [http://en.wikipedia.org/wiki/Decimal_computer]
* Even if the developer would be proficient, most developing environments / technologies limit floating point arithmetic capabilities to a very limited subset of IEEE 754: Only one or two data types, no rounding modes, … [http://www.cs.berkeley.edu/~wkahan/JAVAhurt.pdf]* Results are hardly predictable. [https://hal.archives-ouvertes.fr/hal-00128124/en/] All operations produce the best possible accuracy ''at runtime'', this is how floating
-point works. Contrariwise, financial computer systems typically use a [http://en.wikipedia.org/wiki/Fixed-point_arithmetic fixed-point arithmetic] (COBOL, PL/I, …), where overflow and rounding can be precisely predicted ''at compile-time''.* If you do not know the technical details , cf. first bullet , you ignore the fact that the computer lies to you in many situations. For example, when looking at numerical output and the computer says “<code>ans = 0.1</code>,” this is not absolutely correct. In fact, the value is only ''close enough'' to the value 0.1. Additionally, many functions produce limit values (∞ × −∞ = −∞, ∞ ÷ 0 = ∞, ∞ ÷ −0 = −∞, log (0) = −∞), which is sometimes (but not always!) useful when overflow and underflow occur.
Interval arithmetic addresses above problems in its very special way and introduces new possibilities for algorithms. For example, the [http://en.wikipedia.org/wiki/Interval_arithmetic#Interval_Newton_method interval newton method] is able to find ''all'' zeros of a particular function.
=== Input and output ===
Before exercising interval arithmetic, interval objects must be created
, typically from non-interval data. There are interval constants <code>empty</code> and <code>entire</code> and the class constructors <code>infsup</code> for bare intervals and <code>infsupdec</code> for decorated intervals. The class constructors are very sophisticated and can be used with several kinds of parameters: Interval boundaries can be given by numeric values or string values with decimal numbers. Also it is possible to use so called interval literals with square brackets.
octave:1> infsup (1)
ans ⊂ [5.799999999999999e-17, 5.800000000000001e-17]
It is possible to access the exact numeric interval boundaries with the functions <code>inf</code> and <code>sup</code>. The
default text representation of intervals can be created with <code>intervaltotext</code>. The default text representation is not guaranteed to be exact (see function <code>intervaltoexact</code>), because this would massively spam console output. For example, the exact text representation of <code>realmin</code> would be over 700 decimal places long! However, the default text representation is correct as it guarantees to contain the actual boundaries and is accurate enough to separate different boundaries.
octave:7> infsup (1, 1 + eps)
==== Specialized interval constructors ====
Above mentioned interval construction with decimal numbers or numeric data is straightforward. Beyond that, there are more ways to define intervals or interval boundaries.
* Hexadecimal-floating-constant form: Each interval boundary may be defined by a hexadecimal number (optionally containing a point) and an exponent field with an integral power of two as defined by the C99 standard ([http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf ISO/IEC9899, N1256, §220.127.116.11]). This can be used as a convenient way to define interval boundaries in double precision, because the hexadecimal form is much shorter than the decimal representation of many numbers.
* Rational literals: Each interval boundary may be defined as a fraction of two decimal numbers. This is especially useful if interval boundaries shall be tightest enclosures of fractions, that would be hard to write down as a decimal number.
* Uncertain form: The interval as a whole can be defined by a midpoint or upper/lower boundary and an integral number of [http://en.wikipedia.org/wiki/Unit_in_the_last_place “units in last place” (ULPs)] as an uncertainty. The format is <code>''m''?''ruE''</code>, where
=== Reverse arithmetic operations ===
[[File:Reverse-power-functions.png|400px|thumb|right|Reverse power operations.
The relevant subset of the function's domain , where ''x''<sup>''y''</sup> ∈ [2, 3] , is outlined and hatched.]]
Some arithmetic functions also provide reverse mode operations. That is inverse functions with interval constraints. For example the <code>sqrrev</code> can compute the inverse of the <code>sqr</code> function on intervals. The syntax is <code>
X = sqrrev (C, X)</code> and will compute the enclosure of all numbers ''x'' ∈ X that fulfill the constraint ''x''² ∈ C.
In the following example, we compute the constraints for base and exponent of the power function <code>pow</code> as shown in the figure.
=== Numerical operations ===
Some operations on intervals do not return an interval enclosure, but a single number. Most important are <code>inf</code> and <code>sup</code>, which return the interval boundaries
in double precision.
More such operations are <code>mid</code> (approximation of the interval's midpoint), <code>wid</code> (approximation of the interval's width), <code>rad</code> (approximation of the interval's radius), <code>mag</code> and <code>mig</code>.
=== Boolean operations ===
Interval comparison operations produce boolean results. While some comparisons are especially for intervals (subset, interior, ismember, isempty, disjoint, …) others are extensions of simple numerical comparison. For example, the less
(or equal ) comparison is mathematically defined as ∀<sub>''a''</sub> ∃<sub>''b''</sub> ''a'' ≤ ''b'' ∧ ∀<sub>''b''</sub> ∃<sub>''a''</sub> ''a'' ≤ ''b''.
octave:1> infsup (1, 3) <= infsup (2, 4)
=== Matrix operations ===
Above mentioned operations can
usually also be applied to interval vectors and matrices. Many operations use [http://www.gnu.org/software/octave/doc/interpreter/Vectorization-and-Faster-Code-Execution.html#Vectorization-and-Faster-Code-Execution vectorization techniques].
The implemented interval matrix operations comprise: exact dot product, exact matrix multiplication, exact vector sums, (not-exact) matrix inversion, matrix powers and solving linear systems. As a result of missing hardware / low-level library support, these operations are quite slow compared to familiar operations in floating-point arithmetic.
octave:1> A = infsup ([1, 2, 3; 4, 0, 0; 0, 0, 0], [1, 2, 3; 4, 0, 6; 0, 0, 1])
A = 3×3 interval matrix
=== Error handling ===
Due to the nature of set-based interval arithmetic, you should never observe errors during computation. If you do, there either is a bug in the code or there are unsupported data types.
octave:1> infsup (2, 3) / 0