Unformatted version of **ai12s/ai12-0300-1.txt version 1.4**

Other versions for file**ai12s/ai12-0300-1.txt**

Other versions for file

!standard G.2.3(23) 19-02-25 AI12-0300-1/03

!class binding interpretation 19-01-07

!status Amendment 1-2012 19-01-15

!status ARG Approved 11-0-0 19-01-14

!status work item 19-01-07

!status received 18-12-11

!priority Low

!difficulty Easy

!qualifier Clarification

!subject Annex G text for Fixed * integer

!class binding interpretation 19-01-07

!status Amendment 1-2012 19-01-15

!status ARG Approved 11-0-0 19-01-14

!status work item 19-01-07

!status received 18-12-11

!priority Low

!difficulty Easy

!qualifier Clarification

!subject Annex G text for Fixed * integer

!summary

For fixed times integer multiplications, the integer type is always
Standard.Integer.

!question

G.2.3(23) says in part:

A multiplication P * Q of an operand of a fixed point type F by an operand
of an integer type I, or vice-versa, and a division P / Q of an operand of
a fixed point type F by an operand of an integer type I, are also allowed.
In these cases, the result has a type of F; explicit conversion of the
result is never required.

This implies that (any-fixed * any-integer) is supported, when in fact
(any-fixed * Integer) is what that language allows. We had a customer who
presumed there was something wrong with the compiler because it didn't allow
a (fixed * My_Integer_Type) computation without an explicit conversion.

Should this be fixed? (Yes.)

!recommendation

!wording

Modify G.2.3(23):

A multiplication P * Q of an operand of a fixed point type F by an operand
of [an integer type I] {type Integer}, or vice{ }[-]versa, and a division P / Q
of an operand of a fixed point type F by an operand of [an integer type I]
{type Integer}, are also allowed. In these cases, the result has (the)[a]
type of F; explicit conversion of the result is never required. The accuracy
required in these cases is the same as that required for a multiplication
F(P * Q) or a division F(P / Q) obtained by interpreting the operand of the
integer type to have a fixed point type with a small of 1.0.

!discussion

The multiplying operators for fixed point types are defined in 4.5.5, which
include:

function "*"(Left : T; Right : Integer) return T
function "*"(Left : Integer; Right : T) return T
function "/"(Left : T; Right : Integer) return T

No other operators are defined with fixed and integer operands. (The root-real
and root-integer operators are only usable with values of universal types.)

Editor's Note: The original wording used "vice-versa", when the correct
spelling is "vice versa". I was asked to change these throughout the Standard
(uses are about 50-50 for each spelling); such changes refer to this AI and
this note. None of the uses changed are normative (they're all in AARM notes
and user notes), thus there's no value to handling in a presentation AI.

!corrigendum G.2.3(23)

Replace the paragraph:

A multiplication P * Q of an operand of a fixed point type F by an operand of
an integer type I, or vice-versa, and a division P / Q of an operand of a
fixed point type F by an operand of an integer type I, are also allowed. In
these cases, the result has a type of F; explicit conversion of the result is
never required. The accuracy required in these cases is the same as that
required for a multiplication F(P * Q) or a division F(P / Q) obtained by
interpreting the operand of the integer type to have a fixed point type with a
*small* of 1.0.

by:

A multiplication P * Q of an operand of a fixed point type F by an operand of
type Integer, or vice versa, and a division P / Q of an operand of a
fixed point type F by an operand of type Integer, are also allowed. In
these cases, the result has the type of F; explicit conversion of the result is
never required. The accuracy required in these cases is the same as that
required for a multiplication F(P * Q) or a division F(P / Q) obtained by
interpreting the operand of the integer type to have a fixed point type with a
*small* of 1.0.

!ASIS

No ASIS effect.

!ACATS test

This should be covered by the usual tests for 4.5.5, and any accuracy tests
for G.2.3.

!appendix

From: Tucker Taft Sent: Tuesday, December 11, 2018 8:35 AM We just bumped into the following misleading text in G.2.3(23): 23 A multiplication P * Q of an operand of a fixed point type F by an operand of an integer type I, or vice-versa, and a division P / Q of an operand of a fixed point type F by an operand of an integer type I, are also allowed. In these cases, the result has a type of F; explicit conversion of the result is never required. This implies that (any-fixed * any-integer) is supported, when in fact (any-fixed * Integer) is what that language allows. We had a customer who presumed there was something wrong with the compiler because it didn't allow a (fixed * My_Integer_Type) computation without an explicit conversion. The obvious fix to paragraph 6.2.3(23) is as follows: 23 A multiplication P * Q of an operand of a fixed point type F by an operand of [an integer type I] {type Integer}, or vice-versa, and a division P / Q of an operand of a fixed point type F by an operand of [an integer type I] {type Integer}, are also allowed. In these cases, the result has a type of F; explicit conversion of the result is never required. **************************************************************** From: Jean-Pierre Rosen Sent: Tuesday, December 11, 2018 9:33 AM > This implies that (any-fixed * any-integer) is supported, when in fact > (any-fixed * Integer) is what that language allows. True, and I regret it ever since Ada83. It's presumably too late for Ada 2020, but it is one of the few cases where you cannot escape Integer. Maybe due to some resolution issue? **************************************************************** From: Edmond Schonberg Sent: Tuesday, December 11, 2018 9:40 AM The motivation is probably lost to history, but i would imagine that this operation is intended as a scaling of a fixed value by a factor that is a pure number (I would say dimensionless) and Integer is the only one that makes sense, YMMV. **************************************************************** From: Tucker Taft Sent: Tuesday, December 11, 2018 10:13 AM I agree, that is the intent I would associate with this choice. It is similar to the rule for exponentiation, where the exponent has to be Integer. **************************************************************** From: Erhard Ploedereder Sent: Wednesday, December 12, 2018 7:35 PM Hmmm. I look at A.1. and see 29 function "*" (Left : root_integer; Right : root_real) return root_real; 30 function "*" (Left : root_real; Right : root_integer) return root_real; and words elewhere (in 3.*) that make root_real an ancestor of all float and fixed-point types, while root_integer is ancestor to all integer types. What makes you say that the language allows only function "*"(left: any-fixed; Right: Integer) ? **************************************************************** From: Tucker Taft Sent: Wednesday, December 12, 2018 7:44 PM The predefined operators are not inherited. They appear where they are defined to appear in Chapter 4 (see 4.5(9) for the general rule). Yes, this is a language kludge, but it is an *old* kludge... ;-) The only predefined multiplying operators between fixed-point and integer types require Standard.Integer, as defined in 4.5.5. AARM 4.5.5(15.a) addresses the issue about the multiplying operators between root-real and root-integer, and how they are *not* more generally usable. ****************************************************************

Questions? Ask the ACAA Technical Agent