comp.lang.ada
 help / color / mirror / Atom feed
From: "Robert I. Eachus" <rieachus@comcast.net>
Subject: Re: Why no 'Floor for fixed point types
Date: Sat, 25 Oct 2003 22:40:07 GMT
Date: 2003-10-25T22:40:07+00:00	[thread overview]
Message-ID: <3F9AFB67.5080401@comcast.net> (raw)
In-Reply-To: bnen7p$vjo06$1@ID-25716.news.uni-berlin.de

Nick Roberts wrote:
>I said:
>> 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).

First, the mantissa is not "the decimal digits to the left of the 
decimal point."  For a number written in scaled notation: 1.2345E6 it is 
the part of the number before the exponent.  Since in your program you 
are attempting to remove the scaling from a fixed-point type, the name 
Mantissa seemed appropriate.  Change it if you wish.

But you didn't pay attention above.  The compiler allows you to think 
about fixed-point types as if they are real (non-integer) values.  But 
they are not implemented that way.  Any compiler that uses 
floating-point arithmetic to do fixed-point computations has a lot of 
bugs in it.   They just havent been found yet.  (And I think it was ACVC 
1.4 that added a lot of tests which found such bugs.)

Fixed point values are represented as integers.  Their "actual" value is 
the integer times a scale factor 'Small.  If you divide a fixed point 
number by its 'Small, you get an integer.  Doing the arithmetic right 
can be tricky in theory, but most compilers are smart enough to 
recognize that all they need to do is nothing.  That was why I advised 
you to write it that way--compilers are sensitive to that special case:

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

I assume that the Yuk! was about the reference to Unchecked_Conversion. 
  But I think you didn't understand why it was there.  I was not 
encouraging anyone to write that way, but to use 'Small in an idiom the 
compiler should recognize.  I only mentioned the Unchecked_Conversion 
possibility to help people recognize what is going on in this function: 
  NOTHING.  It is a notation to tell the compiler to switch from 
treating the value as having fixed-point type, and to instead look at 
the value as an integer.

> Maybe an example would help.

Okay.

> 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;
> 
>    
>       range Temperature'First*Scale .. Temperature'Last*Scale;

At this point the compiler will give you an error message.  Let's say we 
  fix it:

        type Scaled_Temperature is
                  range Integer(Temperature'First/Temperature'Small)
                       ..Integer(Temperature'Last/Temperature'Small);

>    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;

...Now I understand the problem you think you are solving with this 
code.  With the fix above so it compiles, for lots of values of 
Temperature'Small you will end up dividing by zero.  With other values 
of Temperature'Small you will have overflows.  So the range where your 
method works is fairly small.  For this particular problem though,

     Integer(Float'Floor(Float(X)));

Should do what you want.  (Or what you should want, or something like that.)

-- 
                                                     Robert I. Eachus

"Quality is the Buddha. Quality is scientific reality. Quality is the 
goal of Art. It remains to work these concepts into a practical, 
down-to-earth context, and for this there is nothing more practical or 
down-to-earth than what I have been talking about all along...the repair 
of an old motorcycle."  -- from Zen and the Art of Motorcycle 
Maintenance by Robert Pirsig




  reply	other threads:[~2003-10-25 22:40 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
2003-10-25 22:40       ` Robert I. Eachus [this message]
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