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,FREEMAIL_FROM autolearn=ham autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,55d12b9409d3b4cd X-Google-Attributes: gid103376,public Path: controlnews3.google.com!news2.google.com!news.maxwell.syr.edu!c03.atl99!atl-c02.usenetserver.com!news.usenetserver.com!border1.nntp.ash.giganews.com!nntp.giganews.com!local1.nntp.ash.giganews.com!nntp.comcast.com!news.comcast.com.POSTED!not-for-mail NNTP-Posting-Date: Wed, 05 May 2004 18:07:07 -0500 Date: Wed, 05 May 2004 19:07:06 -0400 From: "Robert I. Eachus" User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.4) Gecko/20030624 Netscape/7.1 (ax) X-Accept-Language: en-us, en MIME-Version: 1.0 Newsgroups: comp.lang.ada Subject: Re: Newbie Question: Casting Issue References: In-Reply-To: Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Message-ID: NNTP-Posting-Host: 24.147.90.114 X-Trace: sv3-y92uraaC0iWK9FaUzxtcN0Qmhs5Ij56HhKdOAyb/yeR+ViyqpF6Ed2h6UZ6EW0H4bSfYJkvidXEWbTA!vNxAg1wd2UWJJE+OHZRgVIJi3t4wikIWLpDkntntK9p7OGD5J6aCuFIXOrJb1g== X-Complaints-To: abuse@comcast.net X-DMCA-Complaints-To: dmca@comcast.net X-Abuse-and-DMCA-Info: Please be sure to forward a copy of ALL headers X-Abuse-and-DMCA-Info: Otherwise we will be unable to process your complaint properly X-Postfilter: 1.1 Xref: controlnews3.google.com comp.lang.ada:295 Date: 2004-05-05T19:07:06-04:00 List-Id: (In what follows I used capitalization consistant with the original poster's. If that bothers anyone, tough. ;-) Davide wrote: > I need your help, please, to solve a casting issue. > > I have an Ada operation, say FLOAT_POINT_OP, which returns a floating point > type, say: FLOAT_POINT_TYPE is digits 9. > > The result of this operation must be assigned to a fixed point type > variable, say: FIX_POINT_TYPE is delta 0.0625 range -10.0 .. 36.5. > > I cannot use Ada exceptions and I must ensure that the assignment will not > throw a type constraint error at run-time. > Then I perform this check: > > FLOAT_VAR >= FLOAT_POINT_TYPE(FIX_POINT_TYPE'FIRST) > and > FLOAT_VAR <= FLOAT_POINT_TYPE(FIX_POINT_TYPE'LAST) > > (where FLOAT_VAR is the floating point type result returned by > FLOAT_POINT_OP) > > and if the check passes then I perform the "crucial" assignment: > > FIX_VAR := FLOAT_VAR. > > Do you think it works fine? Probably, in this case. > Have you better solutions? Yes. > My worry is about the FLOAT_POINT_TYPE(FIX_POINT_TYPE'FIRST) casting. In > particular about the possibility of an introduction of additional decimal > digits, after the last decimal digit of the FIX_POINT_TYPE bounds. I think > that everything should work if the casting preserves at least the number of > decimal digits specified for delta (in this case 4 digits, being delta = > 0.0625) adding possible digits after the fourth. There is some Ada standard > directive about that? Oh,yes. Lots of them. First, RM 3.5.9(8): "The set of values of a fixed point type comprise the integral multiples of a number called the small of the type. For a type defined by an ordinary_fixed_point_definition (an ordinary fixed point type), the small may be specified by an attribute_definition_clause (see 13.3); if so specified, it shall be no greater than the delta of the type. If not specified, the small of an ordinary fixed point type is an implementation-defined power of two less than or equal to the delta." If you are concerned about representable values, which you should be in this case, you will want to add an attribute_definition_clause for FIX_POINT_TYPE'SMALL. The real reason for doing this is portability. If you fix 'SMALL to be the same value as 'DELTA, then you control whether or not there can be representable values of the type that are not multiples of 'SMALL. But there is more: RM 3.5.9(13) "An ordinary_fixed_point_definition defines an ordinary fixed point type whose base range includes at least all multiples of small that are between the bounds specified in the real_range_specification. The base range of the type does not necessarily include the specified bounds themselves." Yes, that does say that 'FIRST and 'LAST need not be representable values of the fixed-point type, and this is deliberate. However, 'FIRST and 'LAST are within 'SMALL of some representable value of the type. (Whew!) Finally, if you check RM 3.5 you will find that 'FIRST and 'LAST are values of the type. (So even if an end-point of the range of a fixed point type is a multiple of 'SMALL that is not a representable value of the type, assigning in your example: FIX_VAR := FIX_POINT_TYPE'FIRST; -- or FIX_VAR := FIX_POINT_TYPE'LAST; will always work. The problem that can occur is that you are using equality tests on floating point numbers. It is possible with some implementations that the value you are testing compares equal to say FIX_POINT_TYPE'LAST, but in fact is slightly larger than that value. Even if FIX_POINT_TYPE'LAST is a model number of FLOAT_POINT_TYPE, a value of type FLOAT_POINT_TYPE, say in an 80-bit register will be slightly larger than FIX_POINT_TYPE'LAST but compare equal to it. Then the language does not gaurantee that the conversion of that value to FIX_POINT_TYPE will not raise Constraint_Error. The easy way to fix that is to test: if FLOAT_VAR > FLOAT_POINT_TYPE(FIX_POINT_TYPE'FIRST) and FLOAT_VAR < FLOAT_POINT_TYPE(FIX_POINT_TYPE'LAST) then FIX_VAR := FLOAT_VAR. else ... What if you want values of -10.0 and 36.5 to convert cleanly? Easy enough, choose the bounds of FIX_POINT_TYPE so that FIX_POINT_TYPE'FIRST is less than -10.0, and FIX_POINT_TYPE'LAST is greater than 36.5. In your example, change your declaration to, say: type FIX_POINT_TYPE is delta 0.0625 range -10.0001 .. 36.5001; for FIX_POINT_TYPE'SMALL use 0.0625; Notice, of course, that the values in the type declaration will determine the range of values that will be converted to FIX_POINT_TYPE, even though after the conversion, all of the values will be multiples of FIX_POINT_TYPE'SMALL. I can't tell you how to deal with that issue, you will have to look at your requirements. Yes sometimes those issues are a pain, but getting them right is defined by the problem, not by Ada. -- Robert I. Eachus "The terrorist enemy holds no territory, defends no population, is unconstrained by rules of warfare, and respects no law of morality. Such an enemy cannot be deterred, contained, appeased or negotiated with. It can only be destroyed--and that, ladies and gentlemen, is the business at hand." -- Dick Cheney