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: Tue, 28 Oct 2003 18:10:06 +0000
Date: 2003-10-28T18:10:06+00:00	[thread overview]
Message-ID: <bnmbe0$13563v$1@ID-25716.news.uni-berlin.de> (raw)
In-Reply-To: <3F9AFB67.5080401@comcast.net>

Robert I. Eachus wrote:

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

I'm sorry, you're right about the mantissa. In fact, in your example, I 
think the mantissa would strictly be 0.12345, and the exponent 7, but I 
wouldn't mind being set straight on this point.

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

I understand that fixed point types are intended to be represented as 
integers, and that most Ada implementations do so. I also thought the idea 
was that the Ada 95 standard was framed to permit other representations. I 
have heard that on some machines it makes sense to use the native 
floating-point representation (because the machine has sufficient support 
for operations on this representation).

When you say 'bugs', I guess you mean 'inaccuracies'. I would honestly 
appreciate you saying a bit more on this subject (it is quite important to 
me, as a compiler writer!).

I'm also not really sure as to the point you really making, Robert, so -- 
at the risk of trying your patience -- I'd appreciate any clarification you 
can make.

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

Well, from the point of view of the compiler I am writing, I would be 
grateful for more information on the tricky bits.

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

Yes it was. Surely it is possible that there will be differences between 
the underlying integer an implementation uses for a fixed point type, and 
an apparently equivalent integer type. For example, the implementation may 
offset the value in the former. What works for one implementation is likely 
to be non-portable, and could suddenly fail in many other circumstances too.

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

Okay, I understand that, and that is part of what I was trying to achieve 
with the Scaled_Floor I suggested.

The other part of what I was trying to achieve with this function was the 
'floor' part, where the value is rounded down to the nearest 1/Tf'Small. I 
was suggesting this second part should be done using integer arithmetic 
(after conversion). Are you saying that this part should be done using 
fixed-point arithmetic? (I think you might be right.)

>> Having declared:
>>
>>    Scale: constant := 1/Temperature'Small;
>>
>>       type Scaled_Temperature is
>>          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);

Oops! Well spotted. Possibly this mistake suggests that Scaled_Temperature 
should be a fixed point type, rather than an integer type (with delta 1.0). 
Do you agree?

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

Is that so? Could you please illustrate. Remember, I did specifically say 
that Tf'Delta is less than 1.

> With other values 
> of Temperature'Small you will have overflows.  So the range where your 
> method works is fairly small.

Again, I'd appreciate more information about this.

 > For this particular problem though,
> 
>     Integer(Float'Floor(Float(X)));
> 
> Should do what you want.

But this begs the original question of this thread, doesn't it? Why doesn't 
Ada 95 provide the Floor attribute for fixed point types? I admit I never 
really answered this question, and it's a fair one, isn't it?

Also, is the above formulation (which I think we can assume really would 
convert the value to a floating-point representation, and then use some 
kind of iterative approximation scheme to compute the floor value, and then 
convert to Integer) reasonably efficient?

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

Hehe. Of course, the trick is always to know what you need, rather than 
what you want.

-- 
Nick Roberts




  parent reply	other threads:[~2003-10-28 18:10 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
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 [this message]
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