!standard A.5.4 (00) 97-05-27 AI95-00060/04
!class confirmation 95-07-06
!status WG9 approved (8-0-0) 97-07-04
!status ARG approved (6-0-1) 97-04-11
!status work item 95-07-06
!status received 95-07-06
!priority Medium
!difficulty Medium
!subject No predefined 'Truncate Attribute on Fixed-Point Types
!summary 95-07-06
The Truncation attribute is not defined for fixed-point types.
!question 97-05-08
In section A.5.3 a number of attributes of floating-point types are
defined which could also usefully be applied to fixed-point types.
This comment was prompted by the lack of the truncation attribute
for fixed-point types. Consider the following:
type Time_Of_Day is mod 86_400;
T : Time_Of_Day := Time_Of_Day (Ada.Calendar.Seconds(Ada.Calendar.Clock));
Under the rules given in the Standard for modular types (4.6(29)) this
would be legal; the result of Ada.Calendar.Seconds(Ada.Calendar.Clock)
is of type Day_Duration which is then rounded to give a result in the
range 0..86_400 which is then reduced mod 86_400 to a Time_Of_Day value.
Under the rules given in RM95-4.6(28) this will now give a constraint
error if the result rounds up to 86_400. The "mod" operator cannot be
directly applied to the Day_Duration result; the result must be
truncated for this to work. Unfortunately the 'Truncation attribute
cannot be used since it applies only to floating point values and not to
fixed point values.
Possible solutions:
1) Convert to Integer and apply "mod": will not always work as the range
of values for Integer is not guaranteed to be sufficient (RM95-3.5.4(21)).
2) Convert to Float and apply Float'Truncation: will not always work as
Float may not always have 6 digits of precision (RM95-3.5.7(14)).
3) Invent a new integer type with range 0..86_400, convert to this and
apply "mod": will work, but requires the gratuitous introduction of
an extra integer type to handle the conversion.
4) Provide a function which uses an "if" statement to test for the
extreme of the range and produce a result of 0 if the parameter
is >= 86_399.5. This is awkward considering how easy it is to
truncate floating point types.
Recommended solution:
Amend RM95-A.5.4 to provide the Truncation attribute for fixed-point types.
This may also apply to attributes such as Floor, Ceiling, Rounding etc.
There seems to be no good reason why these should be restricted to
floating point types rather than real types in general; the lack of
Truncation in particular leads to unpleasant contortions which are
unnecessary for floating point types, and the extension of attributes
to Truncation would have no impact on existing code since it would simply
be an extension to the current rules.
This extension would have a positive benefit with regard to simplifying an
anomalous situation and avoiding unnecessary complication when performing
common and straightforward operations on real values.
!response 95-07-06
The suggested attribute does not seem useful enough to consider
changing the language.
!appendix 95-07-06
!section A.5.4(00)
!subject Attributes of Fixed-Point Types
!reference RM95-A.5.4
!from John English 95-06-26
!keywords Truncation
!reference as: 95-5171.a John English 95-6-26>>
!discussion
In section A.5.3 a number of attributes of floating-point types are
defined which could also usefully be applied to fixed-point types.
This comment was prompted by the lack of the trucation attribute
for fixed-point types. Consider the following:
type Time_Of_Day is mod 86400;
T : Time_Of_Day := Time_Of_Day (Ada.Calendar.Seconds(Ada.Calendar.Clock));
Under the rules given in RM9X for modular types (RM9X-4.6(29)) this would
be legal; the result of Ada.Calendar.Seconds(Ada.Calendar.Clock) is of
type Day_Duration which is then rounded to give a result in the range
0..86400 which is then reduced mod 86400 to a Time_Of_Day value. Under
the rules given in RM95-4.6(28) this will now give a contraint error if
the result rounds up to 86400. The "mod" operator cannot be directly
applied to the Day_Duration result; the result must be truncated for
this to work. Unfortunately the 'Truncation attribute cannot be used
since it applies only to floating point values and not to fixed point
values.
Possible solutions:
1) Convert to Integer and apply "mod": will not always work as the range
of values for Integer is not guaranteed to be sufficient (RM95-3.5.4(21)).
2) Convert to Float and apply Float'Truncation: will not always work as
Float may not always have 6 digits of precision (RM95-3.5.7(14)).
3) Invent a new integer type with range 0..86400, convert to this and
apply "mod": will work, but requires the gratuitous introduction of
an extra integer type to handle the conversion.
4) Provide a function which uses an "if" statement to test for the
extreme of the range and produce a result of 0 if the parameter
is >= 86399.5. This is awkward considering how easy it is to
truncate floating point types.
Recommended solution:
Amend RM95-A.5.4 to provide the Truncation attribute for fixed-point types.
This may also apply to attributes such as Floor, Ceiling, Rounding etc.
There seems to be no good reason why these should be restricted to
floating point types rather than real types in general; the lack of
Truncation in particular leads to unpleasant contortions which are
unnecessary for floating point types, and the extension of attributes
to Truncation would have no impact on existing code since it would simply
be an extension to the current rules.
This extension would have a positive benefit with regard to simplifying an
anomalous situation and avoiding unnecessary complication when performing
common and straightforward operations on real values.
----------------------------------------------------------------------------
John English | Thoughts for the day:
Dept. of Computing | - People who live in windowed environments
University of Brighton | shouldn't cast pointers
E-mail: je@brighton.ac.uk | - In C++ only your friends can access your
Fax: (+44) 1273 642405 | private parts
----------------------------------------------------------------------------
****************************************************************
!section A.5.4(00)
!subject Attributes of Fixed-Point Types
!reference RM95-A.5.4
!keywords Truncation
!reference 95-5171.a John English
!from Bob Duff
!reference as: 95-5175.a Robert A Duff 95-6-27>>
!discussion
> In section A.5.3 a number of attributes of floating-point types are
> defined which could also usefully be applied to fixed-point types.
> This comment was prompted by the lack of the trucation attribute
> for fixed-point types. Consider the following:
>
> type Time_Of_Day is mod 86400;
> T : Time_Of_Day := Time_Of_Day (Ada.Calendar.Seconds(Ada.Calendar.Clock));
>
> Under the rules given in RM9X for modular types (RM9X-4.6(29)) this would
> be legal; the result of Ada.Calendar.Seconds(Ada.Calendar.Clock) is of
> type Day_Duration which is then rounded to give a result in the range
> 0..86400 which is then reduced mod 86400 to a Time_Of_Day value. Under
> the rules given in RM95-4.6(28) this will now give a contraint error if
> the result rounds up to 86400.
I find the above discussion slightly confusing, since you seem to use
"legal" to mean "does not raise C_E", and you seem to refer "RM9X" as if
it were a particular version of the document. I think what you're
saying is that the run-time semantics of type_conversions to modular
types are different in the final version of the standard than they were
in certain earlier versions, in that out-of-bounds values used to wrap,
whereas they now cause C_E. Is that what you mean? (It's true -- the
language did change in that way.)
> ...The "mod" operator cannot be directly
> applied to the Day_Duration result; the result must be truncated for
> this to work. Unfortunately the 'Truncation attribute cannot be used
> since it applies only to floating point values and not to fixed point
> values.
>
> Possible solutions:
> 1) Convert to Integer and apply "mod": will not always work as the range
> of values for Integer is not guaranteed to be sufficient (RM95-3.5.4(21)).
> 2) Convert to Float and apply Float'Truncation: will not always work as
> Float may not always have 6 digits of precision (RM95-3.5.7(14)).
> 3) Invent a new integer type with range 0..86400, convert to this and
> apply "mod": will work, but requires the gratuitous introduction of
> an extra integer type to handle the conversion.
> 4) Provide a function which uses an "if" statement to test for the
> extreme of the range and produce a result of 0 if the parameter
> is >= 86399.5. This is awkward considering how easy it is to
> truncate floating point types.
Number 3 doesn't seem so bad. You can bury all this in some body.
How often does one need to convert fixed-point to modular?
Do we really need to change the language here? I don't know.
> Recommended solution:
> Amend RM95-A.5.4 to provide the Truncation attribute for fixed-point types.
> This may also apply to attributes such as Floor, Ceiling, Rounding etc.
> There seems to be no good reason why these should be restricted to
> floating point types rather than real types in general; the lack of
> Truncation in particular leads to unpleasant contortions which are
> unnecessary for floating point types, and the extension of attributes
> to Truncation would have no impact on existing code since it would simply
> be an extension to the current rules.
>
> This extension would have a positive benefit with regard to simplifying an
> anomalous situation and avoiding unnecessary complication when performing
> common and straightforward operations on real values.
- Bob
****************************************************************