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=ham autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,6a77269912f77a70 X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 2003-10-25 13:42:35 PST Path: archiver1.google.com!news2.google.com!fu-berlin.de!uni-berlin.de!82-43-33-75.cable.ubr01.croy.blueyonder.co.UK!not-for-mail From: Nick Roberts Newsgroups: comp.lang.ada Subject: Re: Why no 'Floor for fixed point types Date: Sat, 25 Oct 2003 21:42:28 +0100 Message-ID: References: <3F99FBE1.1030601@comcast.net> NNTP-Posting-Host: 82-43-33-75.cable.ubr01.croy.blueyonder.co.uk (82.43.33.75) Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit X-Trace: news.uni-berlin.de 1067114553 33153030 82.43.33.75 (16 [25716]) User-Agent: Mozilla/5.0 (Windows; U; Win95; en-US; rv:1.5) Gecko/20031013 Thunderbird/0.3 X-Accept-Language: en-us, en In-Reply-To: <3F99FBE1.1030601@comcast.net> Xref: archiver1.google.com comp.lang.ada:1675 Date: 2003-10-25T21:42:28+01:00 List-Id: Robert I. Eachus wrote: > ... > Ignore this. To quote 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." So the effect of all the code above can be better accomplished by: > > function Mantissa(X: in Tf) return Ti is > begin return Ti(X/Tf'Small); end Mantissa; No, Robert. Wrong! This function fails to do the 'floor' part of the calculation. The name 'Mantissa' is misleading, since the result will not be the mantissa (the decimal digits to the left of the decimal point) unless Tf'Small happens to be 1.0 (and I did explicitly exclude this case). > -- Technically you could use the constant named Scale above, but there > -- are some potential rounding issues. Writing it this way allows the > -- compiler to convert the division to a multiplication that gives the > -- same result, if it can. For a conforming compiler, there should be no rounding issues in the case Scale=1/Tf'Small, the division is a static expression (which should be calculated precisely at compile time), and I would expect the multiplications to be eliminated. For other scales, of course there will be rounding issues, which must be dealt with; this was rather the point I was trying to emphasise. > -- Of course, any decent compiler should be able to recognize this > -- special case and do nothing. If your compiler doesn't recognize this > -- you could rewrite Mantissa as an instance of Unchecked_Conversion. Yuk! I would suggest you either put up with the redundant operation or get a new compiler. Maybe an example would help. Suppose we have a temperature in variable Temp, of type Temperature (in degrees celsius): type Temperature is delta 0.2 range -15.0 .. 90.0; Temp: Temperature := Read_Sensor(...); Now suppose we have a subsystem that can display two decimal digits (perhaps on a 7-segment LED display), and we can use the following procedure to do it: type Two_Decimal_Digits is range 00..99; procedure Display (Digits: in Two_Decimal_Digits); What we need to be able to do is to convert the fixed point type Temperature into the integer type Two_Decimal_Digits. It might be in the specification that the figure displayed should be the mantissa of the value in Temp; this implies a 'floor' function (rounding down to the nearest whole degree celsius). Having declared: Scale: constant := 1/Temperature'Small; type Scaled_Temperature is range Temperature'First*Scale .. Temperature'Last*Scale; function Scaled_Floor (X: in Temperature) return Scaled_Temperature is subtype ST is Scaled_Temperature; begin return ST(X*Scale) - ST(X*Scale) mod ST(Scale); end; function Mantissa (T: in Temperature) return Two_Decimal_Digits is begin return Two_Decimal_Digits(Scaled_Floor(T)/Scaled_Temperature(Scale)); end; we can now conveniently write: Display( Mantissa(Temp) ); In general, the sequence of events in the calculation will be: scale the value; convert it to an integer; calculate the scaled floor (using integer arithmetic); rescale the result as required. In my example, the Scaled_Floor function scales the value, and the Mantissa function unscales it again. I hope this clarifies things a bit. -- Nick Roberts