# A.5 The Numerics Packages

This Reference Manual output has not been verified, and may contain omissions or errors. Report any problems on the tracking issue

The library package Numerics is the parent of several child units that provide facilities for mathematical computation. One child, the generic package Generic_Elementary_Functions, is defined in A.5.1, together with nongeneric equivalents; two others, the package Float_Random and the generic package Discrete_Random, are defined in A.5.2. Additional (optional) children are defined in Annex G, “Numerics”.

#### Static Semantics

2/1*This paragraph was deleted.*

`package Ada.Numerics `

with Pure is

Argument_Error : exception;

Pi : constant :=

3.14159_26535_89793_23846_26433_83279_50288_41971_69399_37511;

π : constant := Pi;

e : constant :=

2.71828_18284_59045_23536_02874_71352_66249_77572_47093_69996;

end Ada.Numerics;

The Argument_Error exception is raised by a subprogram in a child unit of Numerics to signal that one or more of the actual subprogram parameters are outside the domain of the corresponding mathematical function.

#### Implementation Permissions

5The implementation may specify the values of Pi and e to a larger number of significant digits.

#### Extensions to Ada 83

#### Extensions to Ada 95

## A.5.1 Elementary Functions

1Implementation-defined approximations to the mathematical functions known as the “elementary functions” are provided by the subprograms in Numerics.Generic_Elementary_Functions. Nongeneric equivalents of this generic package for each of the predefined floating point types are also provided as children of Numerics.

#### Static Semantics

2The generic library package Numerics.Generic_Elementary_Functions has the following declaration:

```
generic
type Float_Type is digits <>;
package Ada.Numerics.Generic_Elementary_Functions
with Pure, Nonblocking is
4function Sqrt (X : Float_Type'Base) return Float_Type'Base;
function Log (X : Float_Type'Base) return Float_Type'Base;
function Log (X, Base : Float_Type'Base) return Float_Type'Base;
function Exp (X : Float_Type'Base) return Float_Type'Base;
function "**" (Left, Right : Float_Type'Base) return Float_Type'Base;
5function Sin (X : Float_Type'Base) return Float_Type'Base;
function Sin (X, Cycle : Float_Type'Base) return Float_Type'Base;
function Cos (X : Float_Type'Base) return Float_Type'Base;
function Cos (X, Cycle : Float_Type'Base) return Float_Type'Base;
function Tan (X : Float_Type'Base) return Float_Type'Base;
function Tan (X, Cycle : Float_Type'Base) return Float_Type'Base;
function Cot (X : Float_Type'Base) return Float_Type'Base;
function Cot (X, Cycle : Float_Type'Base) return Float_Type'Base;
6function Arcsin (X : Float_Type'Base) return Float_Type'Base;
function Arcsin (X, Cycle : Float_Type'Base) return Float_Type'Base;
function Arccos (X : Float_Type'Base) return Float_Type'Base;
function Arccos (X, Cycle : Float_Type'Base) return Float_Type'Base;
function Arctan (Y : Float_Type'Base;
X : Float_Type'Base := 1.0)
return Float_Type'Base;
function Arctan (Y : Float_Type'Base;
X : Float_Type'Base := 1.0;
Cycle : Float_Type'Base) return Float_Type'Base;
function Arccot (X : Float_Type'Base;
Y : Float_Type'Base := 1.0)
return Float_Type'Base;
function Arccot (X : Float_Type'Base;
Y : Float_Type'Base := 1.0;
Cycle : Float_Type'Base) return Float_Type'Base;
7function Sinh (X : Float_Type'Base) return Float_Type'Base;
function Cosh (X : Float_Type'Base) return Float_Type'Base;
function Tanh (X : Float_Type'Base) return Float_Type'Base;
function Coth (X : Float_Type'Base) return Float_Type'Base;
function Arcsinh (X : Float_Type'Base) return Float_Type'Base;
function Arccosh (X : Float_Type'Base) return Float_Type'Base;
function Arctanh (X : Float_Type'Base) return Float_Type'Base;
function Arccoth (X : Float_Type'Base) return Float_Type'Base;
8end Ada.Numerics.Generic_Elementary_Functions;
```

9/1{*8652/0020*} The library package Numerics.Elementary_Functions is declared pure and defines the same subprograms as Numerics.Generic_Elementary_Functions, except that the predefined type Float is systematically substituted for Float_Type'Base throughout. Nongeneric equivalents of Numerics.Generic_Elementary_Functions for each of the other predefined floating point types are defined similarly, with the names Numerics.Short_Elementary_Functions, Numerics.Long_Elementary_Functions, etc.

The functions have their usual mathematical meanings. When the Base parameter is specified, the Log function computes the logarithm to the given base; otherwise, it computes the natural logarithm. When the Cycle parameter is specified, the parameter X of the forward trigonometric functions (Sin, Cos, Tan, and Cot) and the results of the inverse trigonometric functions (Arcsin, Arccos, Arctan, and Arccot) are measured in units such that a full cycle of revolution has the given value; otherwise, they are measured in radians.

The computed results of the mathematically multivalued functions are rendered single-valued by the following conventions, which are meant to imply the principal branch:

- The results of the Sqrt and Arccosh functions and that of the exponentiation operator are nonnegative.
- The result of the Arcsin function is in the quadrant containing the point (1.0,
*x*), where*x*is the value of the parameter X. This quadrant is I or IV; thus, the range of the Arcsin function is approximately –π/2.0 to π/2.0 (–Cycle/4.0 to Cycle/4.0, if the parameter Cycle is specified). 14 - The result of the Arccos function is in the quadrant containing the point (
*x*, 1.0), where*x*is the value of the parameter X. This quadrant is I or II; thus, the Arccos function ranges from 0.0 to approximately π (Cycle/2.0, if the parameter Cycle is specified). 15 - The results of the Arctan and Arccot functions are in the quadrant containing the point (
*x*,*y*), where*x*and*y*are the values of the parameters X and Y, respectively. This may be any quadrant (I through IV) when the parameter X (resp., Y) of Arctan (resp., Arccot) is specified, but it is restricted to quadrants I and IV (resp., I and II) when that parameter is omitted. Thus, the range when that parameter is specified is approximately –π to π (–Cycle/2.0 to Cycle/2.0, if the parameter Cycle is specified); when omitted, the range of Arctan (resp., Arccot) is that of Arcsin (resp., Arccos), as given above. When the point (*x*,*y*) lies on the negative x-axis, the result approximates 16 - π (resp., –π) when the sign of the parameter Y is positive (resp., negative), if Float_Type'Signed_Zeros is True;
- π, if Float_Type'Signed_Zeros is False.

(In the case of the inverse trigonometric functions, in which a result lying on or near one of the axes may not be exactly representable, the approximation inherent in computing the result may place it in an adjacent quadrant, close to but on the wrong side of the axis.)

#### Dynamic Semantics

19The exception Numerics.Argument_Error is raised, signaling a parameter value outside the domain of the corresponding mathematical function, in the following cases:

- by any forward or inverse trigonometric function with specified cycle, when the value of the parameter Cycle is zero or negative;
- by the Log function with specified base, when the value of the parameter Base is zero, one, or negative;
- by the Sqrt and Log functions, when the value of the parameter X is negative;
- by the exponentiation operator, when the value of the left operand is negative or when both operands have the value zero;
- by the Arcsin, Arccos, and Arctanh functions, when the absolute value of the parameter X exceeds one;
- by the Arctan and Arccot functions, when the parameters X and Y both have the value zero;
- by the Arccosh function, when the value of the parameter X is less than one; and
- by the Arccoth function, when the absolute value of the parameter X is less than one.

The exception Constraint_Error is raised, signaling a pole of the mathematical function (analogous to dividing by zero), in the following cases, provided that Float_Type'Machine_Overflows is True:

- by the Log, Cot, and Coth functions, when the value of the parameter X is zero;
- by the exponentiation operator, when the value of the left operand is zero and the value of the exponent is negative;
- by the Tan function with specified cycle, when the value of the parameter X is an odd multiple of the quarter cycle;
- by the Cot function with specified cycle, when the value of the parameter X is zero or a multiple of the half cycle; and
- by the Arctanh and Arccoth functions, when the absolute value of the parameter X is one.

[Constraint_Error can also be raised when a finite result overflows (see G.2.4); this may occur for parameter values sufficiently *near* poles, and, in the case of some of the functions, for parameter values with sufficiently large magnitudes.] When Float_Type'Machine_Overflows is False, the result at poles is unspecified.

When one parameter of a function with multiple parameters represents a pole and another is outside the function's domain, the latter takes precedence and Numerics.Argument_Error is raised .

#### Implementation Requirements

36In the implementation of Numerics.Generic_Elementary_Functions, the range of intermediate values allowed during the calculation of a final result shall not be affected by any range constraint of the subtype Float_Type.

In the following cases, evaluation of an elementary function shall yield the *prescribed result*, provided that the preceding rules do not call for an exception to be raised:

- When the parameter X has the value zero, the Sqrt, Sin, Arcsin, Tan, Sinh, Arcsinh, Tanh, and Arctanh functions yield a result of zero, and the Exp, Cos, and Cosh functions yield a result of one.
- When the parameter X has the value one, the Sqrt function yields a result of one, and the Log, Arccos, and Arccosh functions yield a result of zero.
- When the parameter Y has the value zero and the parameter X has a positive value, the Arctan and Arccot functions yield a result of zero.
- The results of the Sin, Cos, Tan, and Cot functions with specified cycle are exact when the mathematical result is zero; those of the first two are also exact when the mathematical result is ± 1.0.
- Exponentiation by a zero exponent yields the value one. Exponentiation by a unit exponent yields the value of the left operand. Exponentiation of the value one yields the value one. Exponentiation of the value zero yields the value zero.

Other accuracy requirements for the elementary functions, which apply only in implementations conforming to the Numerics Annex, and then only in the “strict” mode defined there (see G.2), are given in G.2.4.

When Float_Type'Signed_Zeros is True, the sign of a zero result shall be as follows:

- A prescribed zero result delivered
*at the origin*by one of the odd functions (Sin, Arcsin, Sinh, Arcsinh, Tan, Arctan or Arccot as a function of Y when X is fixed and positive, Tanh, and Arctanh) has the sign of the parameter X (Y, in the case of Arctan or Arccot). 46 - A prescribed zero result delivered by one of the odd functions
*away from the origin*, or by some other elementary function, has an implementation-defined sign.

- [A zero result that is not a prescribed result (that is , one that results from rounding or underflow) has the correct mathematical sign.]

#### Implementation Permissions

48/5The nongeneric equivalent packages can be actual instantiations of the generic package for the appropriate predefined type, though that is not required.

#### Wording Changes from Ada 83

- The generic package is a child unit of the package defining the Argument_Error exception.
- DIS 11430 specified names for the nongeneric equivalents, if provided. Here, those nongeneric equivalents are required.
- Implementations are not allowed to impose an optional restriction that the generic actual parameter associated with Float_Type be unconstrained. (In view of the ability to declare variables of subtype Float_Type'Base in implementations of Numerics.Generic_Elementary_Functions, this flexibility is no longer needed.)
- The sign of a prescribed zero result at the origin of the odd functions is specified, when Float_Type'Signed_Zeros is True. This conforms with recommendations of Kahan and other numerical analysts.
- The dependence of Arctan and Arccot on the sign of a parameter value of zero is tied to the value of Float_Type'Signed_Zeros.
- Sqrt is prescribed to yield a result of one when its parameter has the value one. This guarantee makes it easier to achieve certain prescribed results of the complex elementary functions (see G.1.2, “Complex Elementary Functions”).
- Conformance to accuracy requirements is conditional.

#### Wording Changes from Ada 95

*8652/0020*}

**Corrigendum:**Explicitly stated that the nongeneric equivalents of Generic_Elementary_Functions are pure.

## A.5.2 Random Number Generation

1[Facilities for the generation of pseudo-random floating point numbers are provided in the package Numerics.Float_Random; the generic package Numerics.Discrete_Random provides similar facilities for the generation of pseudo-random integers and pseudo-random values of enumeration types. For brevity, pseudo-random values of any of these types are called *random numbers*.

Some of the facilities provided are basic to all applications of random numbers. These include a limited private type each of whose objects serves as the generator of a (possibly distinct) sequence of random numbers; a function to obtain the “next” random number from a given sequence of random numbers (that is, from its generator); and subprograms to initialize or reinitialize a given generator to a time-dependent state or a state denoted by a single integer.

Other facilities are provided specifically for advanced applications. These include subprograms to save and restore the state of a given generator; a private type whose objects can be used to hold the saved state of a generator; and subprograms to obtain a string representation of a given generator state, or, given such a string representation, the corresponding state.]

#### Static Semantics

4The library package Numerics.Float_Random has the following declaration:

```
package Ada.Numerics.Float_Random
with Global => in out synchronized is
6-- Basic facilities
7type Generator is limited private;
8/5subtype Uniformly_Distributed is Float range 0.0 .. 1.0;
function Random (Gen : Generator) return Uniformly_Distributed
with Global => overriding in out Gen;
9/5procedure Reset (Gen : in Generator;
Initiator : in Integer)
with Global => overriding in out Gen;
procedure Reset (Gen : in Generator)
with Global => overriding in out Gen;
10-- Advanced facilities
11type State is private;
12/5procedure Save (Gen : in Generator;
To_State : out State);
procedure Reset (Gen : in Generator;
From_State : in State)
with Global => overriding in out Gen;
13Max_Image_Width : constant := implementation-defined integer value;
14function Image (Of_State : State) return String;
function Value (Coded_State : String) return State;
15private
... -- not specified by the language
end Ada.Numerics.Float_Random;
```

15.1/2The type Generator needs finalization (see 7.6).

The generic library package Numerics.Discrete_Random has the following declaration:

```
generic
type Result_Subtype is (<>);
package Ada.Numerics.Discrete_Random
with Global => in out synchronized is
18-- Basic facilities
19type Generator is limited private;
20/5function Random (Gen : Generator) return Result_Subtype
with Global => overriding in out Gen;
20.1/5function Random (Gen : Generator;
First : Result_Subtype;
Last : Result_Subtype) return Result_Subtype
with Post => Random'Result in First .. Last,
Global => overriding in out Gen;
21/5procedure Reset (Gen : in Generator;
Initiator : in Integer)
with Global => overriding in out Gen;
procedure Reset (Gen : in Generator)
with Global => overriding in out Gen;
22-- Advanced facilities
23type State is private;
24/5procedure Save (Gen : in Generator;
To_State : out State);
procedure Reset (Gen : in Generator;
From_State : in State)
with Global => overriding in out Gen;
25Max_Image_Width : constant := implementation-defined integer value;
26function Image (Of_State : State) return String;
function Value (Coded_State : String) return State;
27private
... -- not specified by the language
end Ada.Numerics.Discrete_Random;
```

*8652/0097*} The following is a possible implementation of the private part of Numerics.Float_Random (assuming the presence of “

**with**Ada.Finalization;” as a context clause):

`type State is ...;`

type Access_State is access State;

type Generator is new Finalization.Limited_Controlled with

record

S : Access_State := new State'(...);

end record;

procedure Finalize (G : in out Generator);

**in**for all operations on a Generator. For this reason, Numerics.Float_Random and Numerics.Discrete_Random cannot be declared pure.

The type Generator needs finalization (see 7.6) in every instantiation of Numerics.Discrete_Random.

An object of the limited private type Generator is associated with a sequence of random numbers. Each generator has a hidden (internal) state, which the operations on generators use to determine the position in the associated sequence. All generators are implicitly initialized to an unspecified state that does not vary from one program execution to another; they may also be explicitly initialized, or reinitialized, to a time-dependent state, to a previously saved state, or to a state uniquely denoted by an integer value.

An object of the private type State can be used to hold the internal state of a generator. Such objects are only necessary if the application is designed to save and restore generator states or to examine or manufacture them. The implicit initial value of type State corresponds to the implicit initial value of all generators.

The operations on generators affect the state and therefore the future values of the associated sequence. The semantics of the operations on generators and states are defined below.

`function Random (Gen : Generator) return Uniformly_Distributed;`

function Random (Gen : Generator) return Result_Subtype;

Obtains the “next” random number from the given generator, relative to its current state, according to an implementation-defined algorithm.

*This paragraph was deleted.*

`function Random (Gen : Generator;`

First : Result_Subtype;

Last : Result_Subtype) return Result_Subtype

with Post => Random'Result in First .. Last;

Obtains the “next” random number from the given generator, relative to its current state, according to an implementation-defined algorithm. If the range First .. Last is a null range, Constraint_Error is raised.

`procedure Reset (Gen : in Generator;`

Initiator : in Integer);

procedure Reset (Gen : in Generator);

Sets the state of the specified generator to one that is an unspecified function of the value of the parameter Initiator (or to a time-dependent state, if only a generator parameter is specified). The latter form of the procedure is known as the *time-dependent Reset procedure*.

`procedure Save (Gen : in Generator;`

To_State : out State);

procedure Reset (Gen : in Generator;

From_State : in State);

Save obtains the current state of a generator. Reset gives a generator the specified state. A generator that is reset to a state previously obtained by invoking Save is restored to the state it had when Save was invoked.

`function Image (Of_State : State) return String;`

function Value (Coded_State : String) return State;

Image provides a representation of a state coded (in an implementation-defined way) as a string whose length is bounded by the value of Max_Image_Width. Value is the inverse of Image: Value(Image(S)) = S for each state S that can be obtained from a generator by invoking Save.

#### Dynamic Semantics

39Instantiation of Numerics.Discrete_Random with a subtype having a null range raises Constraint_Error.

*This paragraph was deleted.*{*8652/0050*}

#### Bounded (Run-Time) Errors

40.1/5{*8652/0050*} It is a bounded error to invoke Value with a string that is not the image of any generator state. If the error is detected, Constraint_Error or Program_Error is raised. Otherwise, a call to Reset with the resulting state will produce a generator such that calls to Random with this generator will produce a sequence of values of the appropriate subtype, but which are not necessarily random in character. That is, the sequence of values do not necessarily fulfill the implementation requirements of this subclause.

#### Implementation Requirements

40.2/5Each call of a Random function has a *result range*; this is the range First .. Last for the version of Random with First and Last parameters and the range of the result subtype of the function otherwise.

A sufficiently long sequence of random numbers obtained by consecutive calls to Random that have the same generator and result range is approximately uniformly distributed over the result range .

A Random function in an instantiation of Numerics.Discrete_Random is guaranteed to yield each value in its result range in a finite number of calls, provided that the number of such values does not exceed 215.

Other performance requirements for the random number generator, which apply only in implementations conforming to the Numerics Annex, and then only in the “strict” mode defined there (see G.2), are given in G.2.5.

#### Documentation Requirements

44No one algorithm for random number generation is best for all applications. To enable the user to determine the suitability of the random number generators for the intended application, the implementation shall describe the algorithm used and shall give its period, if known exactly, or a lower bound on the period, if the exact period is unknown. Periods that are so long that the periodicity is unobservable in practice can be described in such terms, without giving a numerical bound.

**Documentation Requirement:**The algorithm used for random number generation, including a description of its period.

The implementation also shall document the minimum time interval between calls to the time-dependent Reset procedure that are guaranteed to initiate different sequences, and it shall document the nature of the strings that Value will accept without raising Constraint_Error.

*This paragraph was deleted.*

**Documentation Requirement:**The minimum time interval between calls to the time-dependent Reset procedure that is guaranteed to initiate different random number sequences.

#### Implementation Advice

46Any storage associated with an object of type Generator should be reclaimed on exit from the scope of the object.

**in**. This implies that the full type of Generator probably should be a controlled type, with appropriate finalization to reclaim any heap-allocated storage.

If the generator period is sufficiently long in relation to the number of distinct initiator values, then each possible value of Initiator passed to Reset should initiate a sequence of random numbers that does not, in a practical sense, overlap the sequence initiated by any other value. If this is not possible, then the mapping between initiator values and generator states should be a rapidly varying function of the initiator value.

**mod**M would give a uniform distribution. But this is only true if the period of the underlying generator is a multiple of M. (This usually requires that M be a power of two.) In other cases, the

**mod**operation maps slightly more random values to some result values than others. It is easy to see this: consider a 4-bit random integer (with a range of 0 .. 15). If one

**mod**s this by 6 to get a value in 0 .. 5 (to which one would add 1 to get the value of a die roll), 3 values would be mapped to each value 0 .. 3, but only 2 values would be mapped to 4 and 5. Even when the input is uniformly distributed, the output clearly is not. A similar effect occurs regardless of the number of bits in the random integer. Since it takes care to get this right, users should use the provided functions (which presumably do this correctly – contains a correct algorithm) and resist the urge to “roll-their-own”.

#### Examples

55*Example of a program that plays a simulated dice game:*

`with Ada.Numerics.Discrete_Random;`

procedure Dice_Game is

subtype Die is Integer range 1 .. 6;

subtype Dice is Integer range 2*Die'First .. 2*Die'Last;

package Random_Die is new Ada.Numerics.Discrete_Random (Die);

use Random_Die;

G : Generator;

D : Dice;

begin

Reset (G); -- Start the generator in a unique state in each run

loop

-- Roll a pair of dice; sum and process the results

D := Random(G) + Random(G);

...

end loop;

end Dice_Game;

*Example of a program that simulates coin tosses:*

`with Ada.Numerics.Discrete_Random;`

procedure Flip_A_Coin is

type Coin is (Heads, Tails);

package Random_Coin is new Ada.Numerics.Discrete_Random (Coin);

use Random_Coin;

G : Generator;

begin

Reset (G); -- Start the generator in a unique state in each run

loop

-- Toss a coin and process the result

case Random(G) is

when Heads =>

...

when Tails =>

...

end case;

...

end loop;

end Flip_A_Coin;

*Example of a parallel simulation of a physical system, with a separate generator of event probabilities in each task:*

`with Ada.Numerics.Float_Random;`

procedure Parallel_Simulation is

use Ada.Numerics.Float_Random;

task type Worker is

entry Initialize_Generator (Initiator : in Integer);

...

end Worker;

W : array (1 .. 10) of Worker;

task body Worker is

G : Generator;

Probability_Of_Event : Uniformly_Distributed;

begin

accept Initialize_Generator (Initiator : in Integer) do

Reset (G, Initiator);

end Initialize_Generator;

loop

...

Probability_Of_Event := Random(G);

...

end loop;

end Worker;

begin

-- Initialize the generators in the Worker tasks to different states

for I in W'Range loop

W(I).Initialize_Generator (I);

end loop;

... -- Wait for the Worker tasks to terminate

end Parallel_Simulation;

Although each Worker task initializes its generator to a different state, those states will be the same in every execution of the program. The generator states can be initialized uniquely in each program execution by instantiating Ada.Numerics.Discrete_Random for the type Integer in the main procedure, resetting the generator obtained from that instance to a time-dependent state, and then using random integers obtained from that generator to initialize the generators in each Worker task.

#### Incompatibilities With Ada 95

**Amendment**Type Generator in Numerics.Float_Random and in an instance of Numerics.Discrete_Random is defined to need finalization. If the restriction No_Nested_Finalization (see D.7) applies to the partition, and Generator does not have a controlled part, it will not be allowed in local objects in Ada 2005 whereas it would be allowed in original Ada 95. Such code is not portable, as another Ada compiler may have a controlled part in Generator, and thus would be illegal.

#### Wording Changes from Ada 95

*8652/0050*}

**Corrigendum:**Made the passing of an incorrect Image of a generator a bounded error, as it might not be practical to check for problems (if a generator consists of several related values).

#### Wording Changes from Ada 2005

#### Extensions to Ada 2012

## A.5.3 Attributes of Floating Point Types

#### Static Semantics

1The following *representation-oriented attributes* are defined for every subtype S of a floating point type *T*.

S'Machine_Radix

- Yields the radix of the hardware representation of the type
*T*. The value of this attribute is of the type*universal_integer*.

The values of other representation-oriented attributes of a floating point subtype, and of the “primitive function” attributes of a floating point subtype described later, are defined in terms of a particular representation of nonzero values called the *canonical form*. The canonical form (for the type *T*) is the form

± *mantissa* · *T*'Machine_Radix*exponent*

where

*mantissa*is a fraction in the number base*T*'Machine_Radix, the first digit of which is nonzero, and 5*exponent*is an integer.

S'Machine_Mantissa

- Yields the largest value of
*p*such that every value expressible in the canonical form (for the type*T*), having a*p*-digit*mantissa*and an*exponent*between*T*'Machine_Emin and*T*'Machine_Emax, is a machine number (see 3.5.7) of the type*T*. This attribute yields a value of the type*universal_integer*.

*mantissa*.

S'Machine_Emin

- Yields the smallest (most negative) value of
*exponent*such that every value expressible in the canonical form (for the type*T*), having a*mantissa*of*T*'Machine_Mantissa digits, is a machine number (see 3.5.7) of the type*T*. This attribute yields a value of the type*universal_integer*. 8

S'Machine_Emax- Yields the largest (most positive) value of
*exponent*such that every value expressible in the canonical form (for the type*T*), having a*mantissa*of*T*'Machine_Mantissa digits, is a machine number (see 3.5.7) of the type*T*. This attribute yields a value of the type*universal_integer*.

S'Denorm

- Yields the value True if every value expressible in the form

±*mantissa*·*T*'Machine_Radix*T*'Machine_Emin

where*mantissa*is a nonzero*T*'Machine_Mantissa-digit fraction in the number base*T*'Machine_Radix, the first digit of which is zero, is a machine number (see 3.5.7) of the type*T*; yields the value False otherwise. The value of this attribute is of the predefined type Boolean.

The values described by the formula in the definition of S'Denorm are called *denormalized numbers*. A nonzero machine number that is not a denormalized number is a *normalized number*. A normalized number *x* of a given type *T* is said to be *represented in canonical form* when it is expressed in the canonical form (for the type *T*) with a *mantissa* having *T*'Machine_Mantissa digits; the resulting form is the *canonical-form representation* of *x*.

S'Machine_Rounds

- Yields the value True if rounding is performed on inexact results of every predefined operation that yields a result of the type
*T*; yields the value False otherwise. The value of this attribute is of the predefined type Boolean.

- S'Model_Mantissa = S'Machine_Mantissa, so that operand preperturbation never occurs;
- when the exact mathematical result is not a machine number, the result of a predefined operation must be the nearer of the two adjacent machine numbers.

S'Machine_Overflows

- Yields the value True if overflow and divide-by-zero are detected and reported by raising Constraint_Error for every predefined operation that yields a result of the type
*T*; yields the value False otherwise. The value of this attribute is of the predefined type Boolean. 13

S'Signed_Zeros- Yields the value True if the hardware representation for the type
*T*has the capability of representing both positively and negatively signed zeros, these being generated and used by the predefined operations of the type*T*as specified in IEC 559:1989; yields the value False otherwise. The value of this attribute is of the predefined type Boolean.

For every value *x* of a floating point type *T*, the *normalized exponent* of *x* is defined as follows:

- the normalized exponent of zero is (by convention) zero;
- for nonzero
*x*, the normalized exponent of*x*is the unique integer*k*such that*T*'Machine_Radix*k*–1 ≤ |*x*| <*T*'Machine_Radix*k*.

*x*is the value of

*exponent*in the canonical-form representation of

*x*.

*T*'Machine_Emin.

The following *primitive function attributes* are defined for any subtype S of a floating point type *T*.

S'Exponent

- S'Exponent denotes a function with the following specification:

`function S'Exponent (X : T)`

return universal_integer

- The function yields the normalized exponent of
*X*. 21

S'Fraction- S'Fraction denotes a function with the following specification:

`function S'Fraction (X : T)`

return T

- The function yields the value
*X*·*T*'Machine_Radix–*k*, where*k*is the normalized exponent of*X*. A zero result[, which can only occur when*X*is zero,] has the sign of*X*.

*X*is a normalized number, the result is the value obtained by replacing the

*exponent*by zero in the canonical-form representation of

*X*.

*X*is zero, the magnitude of the result is greater than or equal to the reciprocal of

*T*'Machine_Radix and less than one; consequently, the result is always a normalized number, even when

*X*is a denormalized number.

*X*is a denormalized number, the result is the value obtained by replacing the

*exponent*by zero in the canonical-form representation of the result of scaling

*X*up sufficiently to normalize it.

S'Compose

- S'Compose denotes a function with the following specification:

`function S'Compose (Fraction : T;`

Exponent : universal_integer)

return T

- Let
*v*be the value*Fraction*·*T*'Machine_Radix*Exponent*–*k*, where*k*is the normalized exponent of*Fraction*. If*v*is a machine number of the type*T*, or if |*v*| ≥*T*'Model_Small, the function yields*v*; otherwise, it yields either one of the machine numbers of the type*T*adjacent to*v*. Constraint_Error is optionally raised if*v*is outside the base range of S. A zero result has the sign of*Fraction*when S'Signed_Zeros is True.

*Fraction*and

*v*are both normalized numbers, the result is the value obtained by replacing the

*exponent*by

*Exponent*in the canonical-form representation of

*Fraction*.

*Exponent*is less than

*T*'Machine_Emin and

*Fraction*is nonzero, the result is either zero,

*T*'Model_Small, or (if

*T*'Denorm is True) a denormalized number.

S'Scaling

- S'Scaling denotes a function with the following specification:

`function S'Scaling (X : T;`

Adjustment : universal_integer)

return T

- Let
*v*be the value*X*·*T*'Machine_Radix*Adjustment*. If*v*is a machine number of the type*T*, or if |*v*| ≥*T*'Model_Small, the function yields*v*; otherwise, it yields either one of the machine numbers of the type*T*adjacent to*v*. Constraint_Error is optionally raised if*v*is outside the base range of S. A zero result has the sign of*X*when S'Signed_Zeros is True.

*X*and

*v*are both normalized numbers, the result is the value obtained by increasing the

*exponent*by

*Adjustment*in the canonical-form representation of

*X*.

*Adjustment*is sufficiently small (that is , sufficiently negative), the result is either zero,

*T*'Model_Small, or (if

*T*'Denorm is True) a denormalized number.

S'Floor

- S'Floor denotes a function with the following specification:

`function S'Floor (X : T)`

return T

- The function yields the value ⌊
*X*⌋, that is , the largest (most positive) integral value less than or equal to*X*. When*X*is zero, the result has the sign of*X*; a zero result otherwise has a positive sign. 33

S'Ceiling- S'Ceiling denotes a function with the following specification:

`function S'Ceiling (X : T)`

return T

- The function yields the value ⌈
*X*⌉, that is , the smallest (most negative) integral value greater than or equal to*X*. When*X*is zero, the result has the sign of*X*; a zero result otherwise has a negative sign when S'Signed_Zeros is True. 36

S'Rounding- S'Rounding denotes a function with the following specification:

`function S'Rounding (X : T)`

return T

- The function yields the integral value nearest to
*X*, rounding away from zero if*X*lies exactly halfway between two integers. A zero result has the sign of*X*when S'Signed_Zeros is True. 39

S'Unbiased_Rounding- S'Unbiased_Rounding denotes a function with the following specification:

`function S'Unbiased_Rounding (X : T)`

return T

- The function yields the integral value nearest to
*X*, rounding toward the even integer if*X*lies exactly halfway between two integers. A zero result has the sign of*X*when S'Signed_Zeros is True. 41.1/2

S'Machine_Rounding- S'Machine_Rounding denotes a function with the following specification:

`function S'Machine_Rounding (X : T)`

return T

- The function yields the integral value nearest to
*X*. If*X*lies exactly halfway between two integers, one of those integers is returned, but which of them is returned is unspecified. A zero result has the sign of*X*when S'Signed_Zeros is True. This function provides access to the rounding behavior which is most efficient on the target processor.

S'Truncation

- S'Truncation denotes a function with the following specification:

`function S'Truncation (X : T)`

return T

- The function yields the value ⌈
*X*⌉ when*X*is negative, and ⌊*X*⌋ otherwise. A zero result has the sign of*X*when S'Signed_Zeros is True. 45

S'Remainder- S'Remainder denotes a function with the following specification:

`function S'Remainder (X, Y : T)`

return T

- For nonzero
*Y*, let*v*be the value*X*–*n*·*Y*, where*n*is the integer nearest to the exact value of*X*/*Y*; if |*n*–*X*/*Y*| = 1/2, then*n*is chosen to be even. If*v*is a machine number of the type*T*, the function yields*v*; otherwise, it yields zero. Constraint_Error is raised if*Y*is zero. A zero result has the sign of*X*when S'Signed_Zeros is True.

*Y*.

*X*and

*Y*of the type

*T*,

*v*is necessarily a machine number of the type

*T*, except when

*Y*is in the neighborhood of zero,

*X*is sufficiently close to a multiple of

*Y*, and

*T*'Denorm is False.

S'Adjacent

- S'Adjacent denotes a function with the following specification:

`function S'Adjacent (X, Towards : T)`

return T

- If
*Towards*=*X*, the function yields*X*; otherwise, it yields the machine number of the type*T*adjacent to*X*in the direction of*Towards*, if that machine number exists. If the result would be outside the base range of S, Constraint_Error is raised. When*T*'Signed_Zeros is True, a zero result has the sign of*X*. When*Towards*is zero, its sign has no bearing on the result.

*T*when

*T*'Denorm is False and the smallest denormalized positive number of the type

*T*when

*T*'Denorm is True.

S'Copy_Sign

- S'Copy_Sign denotes a function with the following specification:

`function S'Copy_Sign (Value, Sign : T)`

return T

- If the value of
*Value*is nonzero, the function yields a result whose magnitude is that of*Value*and whose sign is that of*Sign*; otherwise, it yields the value zero. Constraint_Error is optionally raised if the result is outside the base range of S. A zero result has the sign of*Sign*when S'Signed_Zeros is True.

*not*appear to be negative when compared to zero.) The sign determination is accomplished by transferring the sign of the zero quantity to a nonzero quantity and then testing for a negative result.

S'Leading_Part

- S'Leading_Part denotes a function with the following specification:

`function S'Leading_Part (X : T;`

Radix_Digits : universal_integer)

return T

- Let
*v*be the value*T*'Machine_Radix*k*–*Radix_Digits*, where*k*is the normalized exponent of*X*. The function yields the value

- ⌊
*X*/*v*⌋ ·*v*, when*X*is nonnegative and*Radix_Digits*is positive; 58 - ⌈
*X*/*v*⌉ ·*v*, when*X*is negative and*Radix_Digits*is positive.

- Constraint_Error is raised when
*Radix_Digits*is zero or negative. A zero result[, which can only occur when*X*is zero,] has the sign of*X*.

*X*is nonzero, the result is the value obtained by retaining only the specified number of (leading) significant digits of

*X*(in the machine radix), setting all other digits to zero.

*X*up, if necessary to normalize it, then masking the mantissa so as to retain only the specified number of leading digits, then scaling the result back down if

*X*was scaled up.

S'Machine

- S'Machine denotes a function with the following specification:

`function S'Machine (X : T)`

return T

- If
*X*is a machine number of the type*T*, the function yields*X*; otherwise, it yields the value obtained by rounding or truncating*X*to either one of the adjacent machine numbers of the type*T*. Constraint_Error is raised if rounding or truncating*X*to the precision of the machine numbers results in a value outside the base range of S. A zero result has the sign of*X*when S'Signed_Zeros is True.

The following *model-oriented attributes* are defined for any subtype S of a floating point type *T*.

S'Model_Mantissa

- If the Numerics Annex is not supported, this attribute yields an implementation defined value that is greater than or equal to ⌈
*d*· log(10) / log(*T*'Machine_Radix)⌉ + 1, where*d*is the requested decimal precision of*T*, and less than or equal to the value of*T*'Machine_Mantissa. See G.2.2 for further requirements that apply to implementations supporting the Numerics Annex. The value of this attribute is of the type*universal_integer*. 65

S'Model_Emin- If the Numerics Annex is not supported, this attribute yields an implementation defined value that is greater than or equal to the value of
*T*'Machine_Emin. See G.2.2 for further requirements that apply to implementations supporting the Numerics Annex. The value of this attribute is of the type*universal_integer*. 66

S'Model_Epsilon- Yields the value
*T*'Machine_Radix1 –*T*'Model_Mantissa. The value of this attribute is of the type*universal_real*.

*T*above one which, when added to one, yields a machine number different from one. Further discussion can be found in G.2.2.

S'Model_Small

- Yields the value
*T*'Machine_Radix*T*'Model_Emin – 1. The value of this attribute is of the type*universal_real*.

*T*, that is, the number corresponding to the positive underflow threshold. In some implementations employing a radix-complement representation for the type

*T*, the positive underflow threshold is closer to zero than is the negative underflow threshold, with the consequence that the smallest positive normalized number does not coincide with the positive underflow threshold that is , it exceeds the latter). Further discussion can be found in G.2.2.

S'Model

- S'Model denotes a function with the following specification:

`function S'Model (X : T)`

return T

- If the Numerics Annex is not supported, the meaning of this attribute is implementation defined; see G.2.2 for the definition that applies to implementations supporting the Numerics Annex.

S'Safe_First- Yields the lower bound of the safe range (see 3.5.7) of the type
*T*. If the Numerics Annex is not supported, the value of this attribute is implementation defined; see G.2.2 for the definition that applies to implementations supporting the Numerics Annex. The value of this attribute is of the type*universal_real*. 72

S'Safe_Last- Yields the upper bound of the safe range (see 3.5.7) of the type
*T*. If the Numerics Annex is not supported, the value of this attribute is implementation defined; see G.2.2 for the definition that applies to implementations supporting the Numerics Annex. The value of this attribute is of the type*universal_real*.

#### Incompatibilities With Ada 83

#### Extensions to Ada 83

#### Extensions to Ada 95

## A.5.4 Attributes of Fixed Point Types

#### Static Semantics

1The following *representation-oriented* attributes are defined for every subtype S of a fixed point type *T*.

S'Machine_Radix

- Yields the radix of the hardware representation of the type
*T*. The value of this attribute is of the type*universal_integer*. 3

S'Machine_Rounds- Yields the value True if rounding is performed on inexact results of every predefined operation that yields a result of the type
*T*; yields the value False otherwise. The value of this attribute is of the predefined type Boolean. 4

S'Machine_Overflows- Yields the value True if overflow and divide-by-zero are detected and reported by raising Constraint_Error for every predefined operation that yields a result of the type
*T*; yields the value False otherwise. The value of this attribute is of the predefined type Boolean.

#### Incompatibilities With Ada 83

#### Extensions to Ada 83

## A.5.5 Big Numbers

1/5Support is provided for integer arithmetic involving values larger than those supported by the target machine, and for arbitrary-precision real numbers.

#### Static Semantics

2/5The library package Numerics.Big_Numbers has the following declaration:

`package Ada.Numerics.Big_Numbers`

with Pure, Nonblocking, Global => null is

subtype Field is Integer range 0 .. implementation-defined;

subtype Number_Base is Integer range 2 .. 16;

end Ada.Numerics.Big_Numbers;

#### Extensions to Ada 2012

## A.5.6 Big Integers

#### Static Semantics

1/5The library package Numerics.Big_Numbers.Big_Integers has the following declaration:

```
with Ada.Strings.Text_Buffers;
package Ada.Numerics.Big_Numbers.Big_Integers
with Preelaborate, Nonblocking, Global => in out synchronized is
3/5type Big_Integer is private
with Integer_Literal => From_Universal_Image,
Put_Image => Put_Image;
4/5function Is_Valid (Arg : Big_Integer) return Boolean
with Convention => Intrinsic;
```

`attribute_reference`

applied to a default-initialized object of an integer type (see 13.9.2). The language-provided functions in the Big_Integers package only return values for which Is_Valid is certain to be True. ```
subtype Valid_Big_Integer is Big_Integer
with Dynamic_Predicate => Is_Valid (Valid_Big_Integer),
Predicate_Failure => (raise Program_Error);
6/5function "=" (L, R : Valid_Big_Integer) return Boolean;
function "<" (L, R : Valid_Big_Integer) return Boolean;
function "<=" (L, R : Valid_Big_Integer) return Boolean;
function ">" (L, R : Valid_Big_Integer) return Boolean;
function ">=" (L, R : Valid_Big_Integer) return Boolean;
7/5function To_Big_Integer (Arg : Integer) return Valid_Big_Integer;
8/5subtype Big_Positive is Big_Integer
with Dynamic_Predicate => (if Is_Valid (Big_Positive)
then Big_Positive > 0),
Predicate_Failure => (raise Constraint_Error);
9/5subtype Big_Natural is Big_Integer
with Dynamic_Predicate => (if Is_Valid (Big_Natural)
then Big_Natural >= 0),
Predicate_Failure => (raise Constraint_Error);
10/5function In_Range (Arg, Low, High : Valid_Big_Integer) return Boolean is
(Low <= Arg and Arg <= High);
11/5function To_Integer (Arg : Valid_Big_Integer) return Integer
with Pre => In_Range (Arg,
Low => To_Big_Integer (Integer'First),
High => To_Big_Integer (Integer'Last))
or else raise Constraint_Error;
12/5generic
type Int is range <>;
package Signed_Conversions is
function To_Big_Integer (Arg : Int) return Valid_Big_Integer;
function From_Big_Integer (Arg : Valid_Big_Integer) return Int
with Pre => In_Range (Arg,
Low => To_Big_Integer (Int'First),
High => To_Big_Integer (Int'Last))
or else raise Constraint_Error;
end Signed_Conversions;
13/5generic
type Int is mod <>;
package Unsigned_Conversions is
function To_Big_Integer (Arg : Int) return Valid_Big_Integer;
function From_Big_Integer (Arg : Valid_Big_Integer) return Int
with Pre => In_Range (Arg,
Low => To_Big_Integer (Int'First),
High => To_Big_Integer (Int'Last))
or else raise Constraint_Error;
end Unsigned_Conversions;
14/5function To_String (Arg : Valid_Big_Integer;
Width : Field := 0;
Base : Number_Base := 10) return String
with Post => To_String'Result'First = 1;
15/5function From_String (Arg : String) return Valid_Big_Integer;
16/5function From_Universal_Image (Arg : String) return Valid_Big_Integer
renames From_String;
17/5procedure Put_Image
(Buffer : in out Ada.Strings.Text_Buffers.Root_Buffer_Type'Class;
Arg : in Valid_Big_Integer);
18/5function "+" (L : Valid_Big_Integer) return Valid_Big_Integer;
function "-" (L : Valid_Big_Integer) return Valid_Big_Integer;
function "abs" (L : Valid_Big_Integer) return Valid_Big_Integer;
function "+" (L, R : Valid_Big_Integer) return Valid_Big_Integer;
function "-" (L, R : Valid_Big_Integer) return Valid_Big_Integer;
function "*" (L, R : Valid_Big_Integer) return Valid_Big_Integer;
function "/" (L, R : Valid_Big_Integer) return Valid_Big_Integer;
function "mod" (L, R : Valid_Big_Integer) return Valid_Big_Integer;
function "rem" (L, R : Valid_Big_Integer) return Valid_Big_Integer;
function "**" (L : Valid_Big_Integer; R : Natural)
return Valid_Big_Integer;
function Min (L, R : Valid_Big_Integer) return Valid_Big_Integer;
function Max (L, R : Valid_Big_Integer) return Valid_Big_Integer;
19/5function Greatest_Common_Divisor
(L, R : Valid_Big_Integer) return Big_Positive
with Pre => (L /= 0 and R /= 0) or else raise Constraint_Error;
20/5private
... -- not specified by the language
end Ada.Numerics.Big_Numbers.Big_Integers;
```

21/5To_String and From_String behave analogously to the Put and Get procedures defined in Text_IO.Integer_IO (in particular, with respect to the interpretation of the Width and Base parameters) except that Constraint_Error, not Data_Error, is propagated in error cases and the result of a call to To_String with a Width parameter of 0 and a nonnegative Arg parameter does not include a leading blank. Put_Image calls To_String (passing in the default values for the Width and Base parameters), prepends a leading blank if the argument is nonnegative, and writes the resulting value to the buffer using Text_Buffers.Put.

The other functions have their usual mathematical meanings.

The type Big_Integer needs finalization (see 7.6).

#### Dynamic Semantics

24/5For purposes of determining whether predicate checks are performed as part of default initialization, the type Big_Integer is considered to have a subcomponent that has a `default_expression`

.

`Default_Initialized_Object : Valid_Big_Integer;`

#### Implementation Requirements

25/5No storage associated with a Big_Integer object shall be lost upon assignment or scope exit.

#### Extensions to Ada 2012

## A.5.7 Big Reals

#### Static Semantics

1/5The library package Numerics.Big_Numbers.Big_Reals has the following declaration:

```
with Ada.Numerics.Big_Numbers.Big_Integers;
use all type Big_Integers.Big_Integer;
with Ada.Strings.Text_Buffers;
package Ada.Numerics.Big_Numbers.Big_Reals
with Preelaborate, Nonblocking, Global => in out synchronized is
3/5type Big_Real is private
with Real_Literal => From_Universal_Image,
Put_Image => Put_Image;
4/5function Is_Valid (Arg : Big_Real) return Boolean
with Convention => Intrinsic;
```

`attribute_reference`

applied to a default-initialized object of a real type (see 13.9.2). The language-provided functions in the Big_Reals package only return values for which Is_Valid is certain to be True. ```
subtype Valid_Big_Real is Big_Real
with Dynamic_Predicate => Is_Valid (Valid_Big_Real),
Predicate_Failure => raise Program_Error;
6/5function "/" (Num, Den : Big_Integers.Valid_Big_Integer)
return Valid_Big_Real
with Pre => Den /= 0
or else raise Constraint_Error;
7/5function Numerator
(Arg : Valid_Big_Real) return Big_Integers.Valid_Big_Integer
with Post => (if Arg = 0.0 then Numerator'Result = 0);
```

```
function Denominator (Arg : Valid_Big_Real)
return Big_Integers.Big_Positive
with Post =>
(if Arg = 0.0 then Denominator'Result = 1
else Big_Integers.Greatest_Common_Divisor
(Numerator (Arg), Denominator'Result) = 1);
9/5function To_Big_Real (Arg : Big_Integers.Valid_Big_Integer)
return Valid_Big_Real is (Arg / 1);
10/5function To_Real (Arg : Integer) return Valid_Big_Real is
(Big_Integers.To_Big_Integer (Arg) / 1);
11/5function "=" (L, R : Valid_Big_Real) return Boolean;
function "<" (L, R : Valid_Big_Real) return Boolean;
function "<=" (L, R : Valid_Big_Real) return Boolean;
function ">" (L, R : Valid_Big_Real) return Boolean;
function ">=" (L, R : Valid_Big_Real) return Boolean;
12/5function In_Range (Arg, Low, High : Valid_Big_Real) return Boolean is
(Low <= Arg and Arg <= High);
13/5generic
type Num is digits <>;
package Float_Conversions is
function To_Big_Real (Arg : Num) return Valid_Big_Real;
function From_Big_Real (Arg : Valid_Big_Real) return Num
with Pre => In_Range (Arg,
Low => To_Big_Real (Num'First),
High => To_Big_Real (Num'Last))
or else (raise Constraint_Error);
end Float_Conversions;
14/5generic
type Num is delta <>;
package Fixed_Conversions is
function To_Big_Real (Arg : Num) return Valid_Big_Real;
function From_Big_Real (Arg : Valid_Big_Real) return Num
with Pre => In_Range (Arg,
Low => To_Big_Real (Num'First),
High => To_Big_Real (Num'Last))
or else (raise Constraint_Error);
end Fixed_Conversions;
15/5function To_String (Arg : Valid_Big_Real;
Fore : Field := 2;
Aft : Field := 3;
Exp : Field := 0) return String
with Post => To_String'Result'First = 1;
16/5function From_String (Arg : String) return Valid_Big_Real;
17/5function From_Universal_Image (Arg : String) return Valid_Big_Real
renames From_String;
18/5function From_Universal_Image (Num, Den : String)
return Valid_Big_Real is
(Big_Integers.From_Universal_Image (Num) /
Big_Integers.From_Universal_Image (Den));
19/5function To_Quotient_String (Arg : Valid_Big_Real) return String is
(To_String (Numerator (Arg)) & " / " & To_String (Denominator (Arg)));
function From_Quotient_String (Arg : String) return Valid_Big_Real;
20/5procedure Put_Image
(Buffer : in out Ada.Strings.Text_Buffers.Root_Buffer_Type'Class;
Arg : in Valid_Big_Real);
21/5function "+" (L : Valid_Big_Real) return Valid_Big_Real;
function "-" (L : Valid_Big_Real) return Valid_Big_Real;
function "abs" (L : Valid_Big_Real) return Valid_Big_Real;
function "+" (L, R : Valid_Big_Real) return Valid_Big_Real;
function "-" (L, R : Valid_Big_Real) return Valid_Big_Real;
function "*" (L, R : Valid_Big_Real) return Valid_Big_Real;
function "/" (L, R : Valid_Big_Real) return Valid_Big_Real;
function "**" (L : Valid_Big_Real; R : Integer)
return Valid_Big_Real;
function Min (L, R : Valid_Big_Real) return Valid_Big_Real;
function Max (L, R : Valid_Big_Real) return Valid_Big_Real;
22/5private
... -- not specified by the language
end Ada.Numerics.Big_Numbers.Big_Reals;
```

23/5To_String and From_String behave analogously to the Put and Get procedures defined in Text_IO.Float_IO (in particular, with respect to the interpretation of the Fore, Aft, and Exp parameters), except that Constraint_Error (not Data_Error) is propagated in error cases. From_Quotient_String implements the inverse function of To_Quotient_String; Constraint_Error is propagated in error cases. Put_Image calls To_String, and writes the resulting value to the buffer using Text_Buffers.Put.

For an instance of Float_Conversions or Fixed_Conversions, To_Big_Real is exact (that is, the result represents exactly the same mathematical value as the argument) and From_Big_Real is subject to the same precision rules as a type conversion of a value of type T to the target type Num, where T is a hypothetical floating point type whose model numbers include all of the model numbers of Num as well as the exact mathematical value of the argument.

The other functions have their usual mathematical meanings.

The type Big_Real needs finalization (see 7.6).

#### Dynamic Semantics

27/5For purposes of determining whether predicate checks are performed as part of default initialization, the type Big_Real is considered to have a subcomponent that has a `default_expression`

.

`Default_Initialized_Object : Valid_Big_Real;`

#### Implementation Requirements

28/5No storage associated with a Big_Real object shall be lost upon assignment or scope exit.