Version 1.1 of acs/ac-00258.txt

Unformatted version of acs/ac-00258.txt version 1.1
Other versions for file acs/ac-00258.txt

!standard G.2.3(4)          14-02-09 AC95-00258/00
!class confirmation 14-02-09
!status received no action 14-02-09
!status received 14-01-24
!subject Universal fixed-fixed operation and universal real result
!summary
!appendix

From: Randy Brukardt
Sent: Friday, January 24, 2014  4:50 PM

Someone on comp.lang.ada was trying to work around a possible GNAT bug regarding
the 'Round attribute. They found that the following code works properly for
them:

   type High is delta 0.001 digits 9;
   type Low is delta 0.01 digits 9;

   function Convert (Value : High) return Low is
   begin
      return Low'Round (Value * 1.0);
   end Convert;

This does seem to meet the letter of the RM but not the spirit. In particular,
the result of a fixed-fixed multiply is supposed to identify the type of the
result. (No other multiply defined in 4.5.5 matches "Value * 1.0".) However, in
this case, the expected type is universal_real (that being the type of the
operand of the Round attribute).

This expression does not violate 4.5.5(19.1/2), as that only disallows the
expected type of a fixed-fixed multiply from being Universal_Fixed. It does not
require an explicit conversion if the result is Universal_Real, although
3.5.6(4) seems to imply that a specific fixed point type is intended.

If this expression is intended to be legal, I'm not sure what it does at
runtime. Probably it would get evaluated as a root_real (using the largest
floating point type), I say "probably" because I can't find the rule saying
that. If so, that's very strange, injecting floating point into what is supposed
to be a decimal fixed point expression.

I think this expression ought to be illegal: the result needs to identify a
specific type for the result of the multiply. Am I right? If not, what does this
expression do?

***************************************************************

From: Steve Baird
Sent: Friday, January 24, 2014  5:24 PM

> I think this expression ought to be illegal: the result needs to
> identify a specific type for the result of the multiply.

G.2.3(4) says:
   Multiplications and divisions are allowed between operands of any two
   fixed point types; the result has to be (implicitly or explicitly)
   converted to some other numeric type. For purposes of defining the
   accuracy rules, the multiplication or division and the conversion are
   treated as a single operation whose accuracy depends on three types (
   (those of the operands and the result).

As you point out, it's not clear what this means if that third type is
universal_real. One solution is to make this case illegal. Also as you point
out, the other solution would be to define this case to behave as if the
expected type were root_real. I agree that this does not follow as a consequence
of existing wording (3.5.6(6) in particular) so a wording change of some kind is
needed either way.

Either approach would work, but I agree that we currently have a problem.

***************************************************************

From: Tucker Taft
Sent: Friday, January 24, 2014  8:42 PM

I don't believe there is a problem.  T'Round is mentioned explicitly in G.2.3(4)
as implying a conversion to type T, so that is the result type to use.  And
universal real being one of the operand types is also mentioned explicitly in
G.2.3(6) and G.2.3(22), implying that no conversion happens at all, and instead
a "compatible" small is computed based on the universal real value and from that
it is determined whether the "multiple" is not too big, which determines whether
the perfect or close result set is required.

***************************************************************

From: Randy Brukardt
Sent: Saturday, January 25, 2014  2:08 PM

> I don't believe there is a problem.  T'Round is mentioned explicitly
> in G.2.3(4) as implying a conversion to type T, so that is the result
> type to use.

This is clearly the operative sentence. But my natural reading is not the same
as yours. The sentence just seems to be repeating the semantics of T'Round --
which (internally) includes a conversion. But for the purposes of this
subclause, we want to *be* a conversion. We should have said that: "For the
purposes of this subclause, T'Round is treated as an explicit conversion (with
rounding) to T." Or maybe "For the purposes of this subclause, T'Round acts the
same as an explicit conversion ..." Or even "For the purposes of this subclause,
T'Round is an explicit conversion ..."

This is just a nit though (no change is necessary), as the presence of this
sentence implies (ahem) that T'Round is special somehow, and there really isn't
any other possibility as to how. (And decimal fixed point types are used that
much, anyway.)

Another nit: nothing is said about any other kind of expression that happens to
resolve to universal_real. That's a nit because I can't find any other
expression that could resolve that way. But this is clearly a (language)
maintenance hazard - if we ever add an another attribute with a universal_real
parameter, the odds that we forget to update G.2.3 is very high -- especial if
the attribute is not for fixed point types.

Anyway, I guess I have to agree that nothing is wrong here -- this is an
intended hack in the language. (Not sure why we don't have a similar hack for
truncation for all fixed point types, but that's a different issue.)

***************************************************************

From: Tucker Taft
Sent: Saturday, January 25, 2014  2:22 PM

I agree with you that the wording in G.2.3(4) is ambiguous, but I think the only
reading that really works appropriately with the other rules is the one I
suggest.

***************************************************************

Questions? Ask the ACAA Technical Agent