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
next prev 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