7.2.1 Predefined Numeric Types

- Do not use the predefined numeric types in package
`Standard`

. Use range and digits declarations and let the implementation do the derivation implicitly from the predefined types. - For programs that require greater accuracy than that provided by the global assumptions, define a package that declares a private type and operations as needed; see Pappas (1985) for a full explanation and examples.

`Integer`

on a machine with a 16-bit word. The first example below allows a
compiler to choose a multiword representation if necessary.
Use

type Second_Of_Day is range 0 .. 86_400;rather than

type Second_Of_Day is new Integer range 1 .. 86_400;or

subtype Second_Of_Day is Integer range 1 .. 86_400;

This applies to more than just numerical computation. An easy-to-overlook instance of this problem occurs if you neglect to use explicitly declared types for integer discrete ranges (array sizes, loop ranges, etc.) (see Guidelines 5.5.1 and 5.5.2). If you do not provide an explicit type when specifying index constraints and other discrete ranges, a predefined integer type is assumed.

**Language Ref Manual references:**
3.5.4 Integer Types,
3.5.7 Floating Point Types,
3.5.9 Fixed Point Types,
8.6 The Package Standard,
C Predefined Language Environment,
F Implementation-Dependent Characteristics

7.2.2 Ada Model

- Know the Ada model for floating point types and arithmetic.

**Language Ref Manual references:**
3.5.7 Floating Point Types,
4.5.7 Accuracy of Operations with Real Operands

7.2.3 Analysis

- Carefully analyze what accuracy and precision you really need.

Floating point calculations are done with the equivalent of the implementation's predefined floating point types. The effect of extra "guard" digits in internal computations can sometimes lower the number of digits that must be specified in an Ada declaration. This may not be consistent over implementations where the program is intended to be run. It may also lead to the false conclusion that the declared types are sufficient for the accuracy required.

The numeric type declarations should be chosen to satisfy the lowest precision (smallest number of digits) that will provide the required accuracy. Careful analysis will be necessary to show that the declarations are adequate.

**Language Ref Manual references:**
3.5.7 Floating Point Types,
4.5.7 Accuracy of Operations with Real Operands,
13.7.3 Representation Attributes of Real Types

7.2.4 Accuracy Constraints

- Do not press the accuracy limits of the machine(s).

**Language Ref Manual references:**
4.5.7 Accuracy of Operations with Real Operands,
F Implementation-Dependent Characteristics

7.2.5 Comments

- Comment the analysis and derivation of the numerical aspects of a program.

**Language Ref Manual references:**
2.7 Comments,
3.5.4 Integer Types,
3.5.6 Real Types,
4.5.7 Accuracy of Operations with Real Operands

7.2.6 Precision of Constants

- Use named numbers or universal real expressions rather than constants of any particular type.

note

See also Guideline 3.2.5.

**Language Ref Manual references:**
2.4 Numeric Literals,
3.2 Objects and Named Numbers,
4.1 Universal Expressions,
4.9 Static Expressions and Static Subtypes

7.2.7 Subexpression Evaluation

- Anticipate values of subexpressions to avoid exceeding the range of their type. Use derived types, subtypes, factoring, and range constraints on numeric types as described in Guidelines 3.4.1, 5.3.1, and 5.5.3.

**Language Ref Manual references:**
3.3 Types and Subtypes,
3.3.2 Subtype Declarations,
3.4 Derived Types,
4.4 Expressions,
4.5 Operators and Expression Evaluation,
4.5.7 Accuracy of Operations with Real Operands

7.2.8 Relational Tests

- Use
`<=`

and`>=`

to do relational tests on real valued arguments, avoiding the`<`

,`>`

,`=`

, and`/=`

operations. - Use values of type attributes in comparisons and checking for small values.

absolute "equality" in computation, (3) relative "equality" in storage, and (4) relative "equality" in computation.

abs (X - Y) <= Float_Type'Small -- (1) abs (X - Y) <= Float_Type'Base'Small -- (2) abs (X - Y) <= abs X * Float_Type'Epsilon -- (3) abs (X - Y) <= abs X * Float_Type'Base'Epsilon -- (4) |

And specifically for "equality" to zero:

abs X <= Float_Type'Small -- (1) abs X <= Float_Type'Base'Small -- (2) abs X <= abs X * Float_Type'Epsilon -- (3) abs X <= abs X * Float_Type'Base'Epsilon -- (4) |

`<`

, `>`

,
`=`

, `/=`

) are a general problem in real
valued computations. Because of the way Ada comparisons are defined in terms
of model intervals, it is possible for the values of the Ada comparisons
`A < B`

and `A = B`

to depend on the implementation,
while `A <= B`

evaluates uniformly
across implementations. Note that for real values in Ada,
"`A <= B`

" is not the
same as "`not (A > B)`

".
Further explanation can be found in Cohen (1986) pp.227-233.
Type attributes are the primary means of symbolically accessing the implementation of the Ada numeric model. When the characteristics of the model numbers are accessed symbolically, the source code is portable. The appropriate model numbers of any implementation will then be used by the generated code.

Although zero is technically not a special case, it is often overlooked because it looks like the simplest and, therefore, safest case. But in reality, each time comparisons involve small values, evaluate the situation to determine which technique is appropriate.

note

Regardless of language, real valued computations have inaccuracy. That the corresponding mathematical operations have algebraic properties usually introduces some confusion. This guideline explains how Ada deals with the problem that most languages face.

**Language Ref Manual references:**
4.5.2 Relational Operators and Membership Tests

Back to document index