From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=unavailable autolearn_force=no version=3.4.4 Path: eternal-september.org!reader01.eternal-september.org!reader02.eternal-september.org!news.eternal-september.org!news.eternal-september.org!news.eternal-september.org!feeder.eternal-september.org!news.stack.nl!reality.xs3.de!news.jacob-sparre.dk!loke.jacob-sparre.dk!pnx.dk!.POSTED!not-for-mail From: "Randy Brukardt" Newsgroups: comp.lang.ada Subject: Re: How to round to the nearest fixed-point value? Date: Fri, 24 Jan 2014 16:30:36 -0600 Organization: Jacob Sparre Andersen Research & Innovation Message-ID: References: NNTP-Posting-Host: static-69-95-181-76.mad.choiceone.net X-Trace: loke.gir.dk 1390602636 4909 69.95.181.76 (24 Jan 2014 22:30:36 GMT) X-Complaints-To: news@jacob-sparre.dk NNTP-Posting-Date: Fri, 24 Jan 2014 22:30:36 +0000 (UTC) X-Priority: 3 X-MSMail-Priority: Normal X-Newsreader: Microsoft Outlook Express 6.00.2900.5931 X-RFC2646: Format=Flowed; Original X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.6157 Xref: news.eternal-september.org comp.lang.ada:18292 Date: 2014-01-24T16:30:36-06:00 List-Id: "Natasha Kerensikova" wrote in message news:slrnle4e9r.1lme.lithiumcat@sigil.instinctive.eu... > Hello, > > On 2014-01-22, Natasha Kerensikova wrote: >> function Convert (Value : High) return Low is >> begin >> return Low'Round (Value); >> end Convert; > > In case anyone is interested, the following rewrite works around the > problem: > > function Convert (Value : High) return Low is > begin > return Low'Round (Value * 1.0); > end Convert; I believe the above should be illegal - but in any case, it's not clear from the RM what this means. The only multiply operations available for fixed point types either have one operand that is an integer (not the case above), or produce a Universal_Fixed result. 4.5.5(19.1/2) requires that the result be used in a context where the result type is identified, and specifically disallows the result from being Universal_Fixed. The type of the operand of 'Round is Universal_Real. This appears to meet the letter of the rule, but not the intent (which is that the expected type determine the scaling and respresentation for the result). > I would have thought that the optimizer would have quickly brought both > version to the same generated code, but from -O0 to -O3 I get the > correct rounding with the latter but not with the former. No, the result of the operand here is Universal_Real. I believe the language says that runtime universal values are evaluated using the largest possible numeric type; in this case, that would be a large float type. It's very difficult to optimize out float operations (because of precision issues - you have to be very careful that the precision of the result is the same after optimization), so it probably can't be changed. So you're getting vastly different code. > I guess that's enough to conclude there is a compiler bug somewhere (or > a weird bug in the language). I'll have to send that to AdaCore... I think there might be a bug in the language here (that is, for your rewrite, not for your original code), but I'll ask the ARG. Randy.