!standard 04.09 (38) 04-04-22 AI95-00100/05
!standard 03.05.09 (08)
!class binding interpretation 04-04-22
!status Amendment 200Y 04-07-02
!status ARG Approved 11-0-0 04-06-17
!status work item 04-04-07
!status ARG Approved 9-0-0 04-03-05
!status work item 95-10-21
!status received 95-10-12
!priority Low
!difficulty Medium
!subject Truncation required for static expressions if Machine_Rounds is false
!summary
A static expression of a fixed or floating point type that is not part of a
larger static expression will be rounded or truncated based on the value of
Machine_Rounds for the type.
!question
Is the intent of 4.9(38) to require truncation for values of static
expressions if Machine_Rounds is false? (Yes.)
What are the machine numbers of a fixed point type? (The representable
multiples of small.)
!recommendation
(See wording.)
!wording
Add after the first sentence of 3.5.9(8):
The machine numbers of a fixed point type are the values of the type that can
be represented exactly in every unconstrained variable of the type.
!discussion
Paragraph 4.9(38) reads:
"For a real static expression that is not part of a larger static
expression, and whose expected type is not a descendent of a formal scalar
type, the implementation shall round or truncate the value (according to
the Machine_Rounds attribute of the expected type) to the nearest machine
number of the expected type; if the value is exactly half-way between two
machine numbers, any rounding shall be performed away from zero. If the
expected type is a descendant of a formal scalar type, no special rounding
or truncating is required--normal accuracy rules apply (see Annex G)."
Reading just the first sentence may be confusing, but the second
sentence makes the intent clear: there are special rounding and truncation
rules that only apply to static scalar expressions which are not descended
from a formal scalar type. To do this correctly will require special
effort, but this effort is required in any case since the legality rules
require this evaluation to be done without Overflow_Checks. In other words
this evaluation in general cannot be done using normal machine arithmetic.
There is one subtle problem, though, because 4.9(38) mentions machine numbers,
but machine number are only defined for floating-point types (in 3.5.7(8)). For
4.9(38) to make sense, they must be defined for fixed-point types. So we are
adding a sentence to 3.5.9(8) to provide this definition.
!corrigendum 3.5.9(8)
@drepl
The set of values of a fixed point type comprise the integral multiples of a
number called the @i of the type. For a type defined by an
@fa (an @i fixed point type), the
@i may be specified by an @fa (see 13.3); if so
specified, it shall be no greater than the @i of the type. If not
specified, the @i of an ordinary fixed point type is an
implementation-defined power of two less than or equal to the @i.
@dby
The set of values of a fixed point type comprise the integral multiples of a
number called the @i of the type. The @i of a fixed
point type are the values of the type that can be represented exactly in every
unconstrained variable of the type. For a type defined by an
@fa (an @i fixed point type), the
@i may be specified by an @fa (see 13.3);
if so specified, it shall be no greater than the @i of the type. If not
specified, the @i of an ordinary fixed point type is an
implementation-defined power of two less than or equal to the @i.
!ACATS Test
ACATS tests C490001 and C490002 tests 4.9(38), including the rounding
directions confirmed by this AI (and the fixed point rounding that was not
defined properly). So no further tests are needed.
!appendix
!section 4.9(38)
!subject Truncation required if Machine_Rounds false?
!reference RM95-4.9(38), RM95-A.5.3(11)
!from Jim Ledger 95-10-09
<>
!discussion
The following portion of 4.9(38) can be interpreted to mean that, for a real
static expression that is not part of a larger static expression, if
Machine_Rounds is false for the expected type, the implementation *must*
truncate the value to the nearest machine number:
For a real static expression that is not part of a larger static
expression, and whose expected type is not a descendant of a formal
scalar type, THE IMPLEMENTATION SHALL ROUND OR TRUNCATE THE VALUE
(ACCORDING TO THE MACHINE_ROUNDS ATTRIBUTE OF THE EXPECTED TYPE) to
the nearest machine number of the expected type..."
However, A.5.3(11) says that T'Machine_Rounds is true if rounding is performed
on inexact results of every predefined operation yielding a result of type T,
and is false otherwise. The implication here is that if Machine_Rounds is
false, the implementation *may* but need not truncate the value.
Is the intent of 4.9(38) to *require* truncation for values of static
expressions if Machine_Rounds is false?
Furthermore, I presume (based on e-mail from Tucker Taft in another forum)
that 4.9(38) is intended to apply to fixed point expected types as well as
floating point, even though the concept of "machine numbers" is not defined
for fixed point types. That is, one can substitute "integral multiple of
the small" for "machine number" in 4.9(38) to get the corresponding rule
for fixed point types.
Is truncation (to a multiple of small) *required* if the expected type is
ordinary fixed point and Machine_Rounds is false? What about decimal fixed
point?
The issue for fixed point types is clouded by AARM 4.9(38.d), which implies
that truncation is mandated for static conversion to a fixed point type or
division by integer. I don't see why truncation (regardless of the value of
Machine_Rounds) should be required in all cases, and only for these two
operations. When this paragraph says "...must do truncation..." should it
have said "...must do truncation or rounding...?"
Jim Ledger
ACVC Team
jim@sis.saic.com
****************************************************************
!section 4.9(38)
!subject Truncation required if Machine_Rounds false?
!reference RM95-4.9(38), RM95-A.5.3(11)
!reference 95-5320.a Jim Ledger 95-10-10
!from Ted Baker95-10-11
<>
!discussion
| The issue for fixed point types is clouded by AARM 4.9(38.d), which implies
| that truncation is mandated for static conversion to a fixed point type or
| division by integer. I don't see why truncation (regardless of the value of
| Machine_Rounds) should be required in all cases, and only for these two
| operations. When this paragraph says "...must do truncation..." should it
| have said "...must do truncation or rounding...?"
There is one important reason for requiring truncation for
fixed-point arithmetic. The type Duration is fixed-point.
Real-time programs sometimes need to do potentially inexact
computations with Duration, such as division to convert between a
rate and a period, or multiplication of a period times an
interation count. With truncation, the error introduced by such
computations can be analyzed precisely, and compensation can be
made for cumulative errors. On the other hand, with rounding, it
does not just require more complex computations, but the direction
of single-bit rounding is not predictable (could round up or
down).
The issue is especially important for static expressions, because
of the case of task periods (or other time intervals) that are
specified by constants that cannot be represented exactly in
binary, like 0.001. We need to know what Duration(0.001) means.
--Ted Baker
****************************************************************
!section 4.9(38)
!subject Truncation required if Machine_Rounds false?
!reference RM95-4.9(38), RM95-A.5.3(11)
!reference 95-5320.a Jim Ledger 95-10-10
!reference as: 95-5323.a Ted Baker 95-10-11
!from Robert Dewar 95-10-11
!reference as: 95-5330.a Robert Dewar 95-10-12>>
!discussion
I am surprised that people are seriously considering the possibility of
requiring truncation for (non-decimal) fixed-point. If the RM says this,
it is an unintentional consequence that the ARG should fix. The intention
is that fixed-point semantics in Ada 95 be essentially identical to those
in Ada 83, expect for relaxing some accuracy requirements. We certainly
do NOT want to *add* accuracy requirements. The idea of existing Ada 83
implementations having to go to lots of effort to adjust their existing
implementation of ordinary fixed-point is an unacceptable one. Fixed-point
is simply not important enough to be worth a major incompatible change
(incompatible in the implementation sense, rather than the formal semantic
sense).
****************************************************************
!section 4.9(38)
!subject Truncation required if Machine_Rounds false?
!reference RM95-4.9(38), RM95-A.5.3(11)
!reference 95-5320.a Jim Ledger 95-10-10
!from Jim Ledger 95-10-12
!reference 95-5337.a Jim Ledger 95-10-13>>
!discussion
> There is one important reason for requiring truncation for
> fixed-point arithmetic. The type Duration is fixed-point.
> Real-time programs sometimes need to do potentially inexact
> computations with Duration, such as division to convert between a
> rate and a period, or multiplication of a period times an
> interation count. With truncation, the error introduced by such
> computations can be analyzed precisely, and compensation can be
> made for cumulative errors. On the other hand, with rounding, it
> does not just require more complex computations, but the direction
> of single-bit rounding is not predictable (could round up or
> down).
>
> The issue is especially important for static expressions, because
> of the case of task periods (or other time intervals) that are
> specified by constants that cannot be represented exactly in
> binary, like 0.001. We need to know what Duration(0.001) means.
>
> --Ted Baker
That all sounds reasonable, but does 4.9(38) actually require such
truncation? If so, is it only required if Machine_Rounds is false?
Is it required for decimal as well as ordinary fixed point types?
Is it required for floating point types as well (when Machine_Rounds
is false)?
Jim Ledger
ACVC Team
jim@sis.saic.com
****************************************************************
!section 4.9(38)
!subject Truncation required if Machine_Rounds false?
!reference RM95-4.9(38), RM95-A.5.3(11)
!reference 95-5320.a Jim Ledger 95-10-10
!reference as: 95-5323.a Ted Baker 95-10-11
!reference 95-5330.a Robert Dewar 95-10-12
!from Ted Baker 95-10-13
!reference 95-5338.a Ted Baker 95-10-13>>
!discussion
| I am surprised that people are seriously considering the possibility of
| requiring truncation for (non-decimal) fixed-point. If the RM says this,
| it is an unintentional consequence that the ARG should fix.
You should not be surprised, and it is intentional, since we had a
rather lengthy discussion of it at a WG9 meeting in Boston.
--Ted Baker
****************************************************************
Editor's note:
The priority of this AI was changed based on ARG discussion in November 2000.
****************************************************************
From: Randy Brukardt
Sent: Wednesday, April 7, 2004 8:26 PM
We approved several dormant AIs at the last meeting without going back to
see what the last discussion of the AI had decided. I've done this as part
of creating the minutes. It appears that AI-100 has a significant issue that
hasn't been addressed.
In Burlington (meeting 8), we decided that the basic question answer was
correct. However, this paragraph (4.9(38)) applies to all real static
expressions - which obviously includes fixed point static expressions. But
fixed point static expressions don't have machine numbers. So what does this
paragraph mean for a fixed point static expression?
The conclusion in Burlington was to define a machine number of a fixed point
type to be a multiple of the Small. Wording was intended to be added to
address this.
The adjustments to 4.9(38) in AI-268 also do not address this problem. It
seems to me that it ought to be addressed.
****************************************************************