comp.lang.ada
 help / color / mirror / Atom feed
From: Nick Roberts <nick.roberts@acm.org>
Subject: Re: Why no 'Floor for fixed point types
Date: Sat, 25 Oct 2003 21:42:28 +0100
Date: 2003-10-25T21:42:28+01:00	[thread overview]
Message-ID: <bnen7p$vjo06$1@ID-25716.news.uni-berlin.de> (raw)
In-Reply-To: <3F99FBE1.1030601@comcast.net>

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




  reply	other threads:[~2003-10-25 20:42 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-10-23 20:09 Why no 'Floor for fixed point types Duncan Sands
2003-10-23 22:06 ` Robert I. Eachus
2003-10-24 16:00   ` Stephen Leake
2003-10-24 18:13     ` Duncan Sands
2003-10-23 23:10 ` Martin Dowie
2003-10-24 21:46 ` Nick Roberts
2003-10-25  4:29   ` Robert I. Eachus
2003-10-25 20:42     ` Nick Roberts [this message]
2003-10-25 22:40       ` Robert I. Eachus
2003-10-27 18:59         ` Randy Brukardt
2003-10-28  1:19           ` Robert I. Eachus
2003-10-28 18:23             ` Nick Roberts
2003-10-28 18:34               ` Stephane Richard
2003-10-29 19:26               ` Randy Brukardt
2003-10-30  4:55                 ` Robert I. Eachus
2003-10-28 18:10         ` Nick Roberts
2003-10-27 18:49       ` Randy Brukardt
2003-10-28 18:32         ` Nick Roberts
2003-10-29 19:29           ` Randy Brukardt
2003-10-30 23:41             ` Nick Roberts
2003-10-31 22:25               ` Randy Brukardt
2003-11-06  2:41                 ` Nick Roberts
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox