!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. ***************************************************************