comp.lang.ada
 help / color / mirror / Atom feed
* Question about ordinary fixed point types.
@ 2010-08-15 21:43 Peter C. Chapin
  2010-08-15 21:55 ` Shark8
                   ` (3 more replies)
  0 siblings, 4 replies; 28+ messages in thread
From: Peter C. Chapin @ 2010-08-15 21:43 UTC (permalink / raw)


I have a need to work with ordinary fixed point types. I've read the in
the reference manual about them (section 3.5.9, for example), and some
other things. I still have a few questions. I thought I'd start with one
here.

Consider this example:


type Angle_Type is delta 0.0005 range -3.1416 .. 3.1416;
Angle : Angle_Type;
...
Angle := Angle_Type'First;
while Angle < Angle_Type'Last loop
  -- Work with Angle here.
  Angle := Angle + Angle_Type'Small;
end loop;


Aside from Angle_Type'Last does the loop above reliably visit every
possible value of Angle_Type? By "reliably" I mean "has the desired
effect on all possible correct Ada implementations." I guess my question
is: does Angle + Angle_Type'Small always advance Angle to the next
machine number in the type?

I'm using GNAT GPL 2010 and in the example above GNAT appears to be
using 2**(-11) for Angle_Type'Small. It thus uses something over 12,000
values for the type. The code above is for a test program; it is my
intention to exercise every possible value.

As an aside it appears as if Angle_Type'First is actually slightly less
than the -3.1416 mentioned in the type definition. My reading of the Ada
standard is that this is okay. Specifically I should be getting a
multiple of Angle_Type'Small that is closest to the mathematical value
of -3.1416. Apparently the closest multiple is just "to the left" of the
number I specified. This actually works out to be slightly awkward in my
case, but that's a problem I can probably figure out.

Thanks!

Peter



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: Question about ordinary fixed point types.
  2010-08-15 21:43 Question about ordinary fixed point types Peter C. Chapin
@ 2010-08-15 21:55 ` Shark8
  2010-08-16  0:46   ` Peter C. Chapin
  2010-08-15 22:08 ` Yannick Duchêne (Hibou57)
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 28+ messages in thread
From: Shark8 @ 2010-08-15 21:55 UTC (permalink / raw)


> type Angle_Type is delta 0.0005 range -3.1416 .. 3.1416;

The first thing I see here is that 0.0005 doesn't evenly divide
2*3.1416; is that going to be a problem? {I haven't used fixed-point
types yet; but that looks like something you'd generally want: an even
division of (Type'Last-Type'First) into 'delta'.}

So, will changing the delta to 0.0002, 0.0001, OR 0.00005 be doable/
convenient/preferable-if-possible?



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: Question about ordinary fixed point types.
  2010-08-15 21:43 Question about ordinary fixed point types Peter C. Chapin
  2010-08-15 21:55 ` Shark8
@ 2010-08-15 22:08 ` Yannick Duchêne (Hibou57)
  2010-08-16  1:03   ` Peter C. Chapin
  2010-08-16 11:02 ` Stephen Leake
  2010-08-20  1:21 ` Yannick Duchêne (Hibou57)
  3 siblings, 1 reply; 28+ messages in thread
From: Yannick Duchêne (Hibou57) @ 2010-08-15 22:08 UTC (permalink / raw)


Hi Peter, nice to see you again,

Le Sun, 15 Aug 2010 23:43:43 +0200, Peter C. Chapin <chapinp@acm.org> a  
écrit:

> I have a need to work with ordinary fixed point types. I've read the in
> the reference manual about them (section 3.5.9, for example), and some
> other things. I still have a few questions. I thought I'd start with one
> here.
>
> Consider this example:
>
>
> type Angle_Type is delta 0.0005 range -3.1416 .. 3.1416;
> Angle : Angle_Type;
> ...
> Angle := Angle_Type'First;
> while Angle < Angle_Type'Last loop
>   -- Work with Angle here.
>   Angle := Angle + Angle_Type'Small;
> end loop;
OK.


> Aside from Angle_Type'Last does the loop above reliably visit every
> possible value of Angle_Type? By "reliably" I mean "has the desired
> effect on all possible correct Ada implementations." I guess my question
> is: does Angle + Angle_Type'Small always advance Angle to the next
> machine number in the type?
What do you mean with “to the next machine number in the type” ? That this  
may not advance in some case ?

> I'm using GNAT GPL 2010 and in the example above GNAT appears to be
> using 2**(-11) for Angle_Type'Small.
So a bit less than the desired 0.0005

If the matter is the precise exploration of a precise set of points in a  
range, I may have a silly suggestion (silly in some sense, while not so  
much in some others) : why not use an array of predefined points ? Here,  
you would have an array of 12566 points. Ok, this may seems a big array,  
some design for hight efficiency. But this would come with the benefit of  
an precise and may be adjustable point by point, set of points. The  
Quality of this set of point could be precisely evaluated and adjusted.  
This is relevant here, as any way, you will never get exact value, because  
as you noticed, the delta does not allow to exactly match the range.

What is the purpose of the exploration ? Sampling at normalized position  
or something of the like ?

I would be very interested to know more about the intended use. This will  
learn us a lot of things.


-- 
There is even better than a pragma Assert: a SPARK --# check.
--# check C and WhoKnowWhat and YouKnowWho;
--# assert Ada;
--  i.e. forget about previous premises which leads to conclusion
--  and start with new conclusion as premise.



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: Question about ordinary fixed point types.
  2010-08-15 21:55 ` Shark8
@ 2010-08-16  0:46   ` Peter C. Chapin
  2010-08-16  4:13     ` Jeffrey Carter
  0 siblings, 1 reply; 28+ messages in thread
From: Peter C. Chapin @ 2010-08-16  0:46 UTC (permalink / raw)


On 2010-08-15 17:55, Shark8 wrote:

>> type Angle_Type is delta 0.0005 range -3.1416 .. 3.1416;
> 
> The first thing I see here is that 0.0005 doesn't evenly divide
> 2*3.1416; is that going to be a problem?

In theory it is not a problem. My reading of the Ada Reference Manual
tells me that the implementation chooses a value of Small (the actual
difference between represented numbers) that is no more than the
specified delta. Note that Small must be a power of 2, but can be
controlled with a representation clause. In my case GNAT appears to be
using 2**(-11) which is 0.0004883. Implementations can choose a smaller
Small if they want.

The values in the type then become all the multiples of Small "between"
the endpoints of the specified range. However, those endpoints are
converted to the nearest multiple of Small (unless they fall exactly
between two multiples in which case the value closer to zero wins). You
can probably tell I've been reading the manual. :)

I'm not sure which multiple of 2**(-11) are involved here exactly but it
appears that the mathematical value of -3.1416 is rounding down...
meaning more negative. I'm not too worried about that right now. I just
wondered how I could visit all the values of the type in a loop.

Probably I should use extra digits in the definition of the range to
communicate my intentions to the compiler more precisely. Thus

type Angle_Type is delta 0.0005 range -3.1415926535 .. 3.1415926535;

That way when the compiler decides how to round the end points of the
range, it will definitely do the right thing.

Peter



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: Question about ordinary fixed point types.
  2010-08-15 22:08 ` Yannick Duchêne (Hibou57)
@ 2010-08-16  1:03   ` Peter C. Chapin
  2010-08-16  4:11     ` Jeffrey Carter
  2010-08-16  9:23     ` Simon Wright
  0 siblings, 2 replies; 28+ messages in thread
From: Peter C. Chapin @ 2010-08-16  1:03 UTC (permalink / raw)


On 2010-08-15 18:08, Yannick Duchêne (Hibou57) wrote:

> Hi Peter, nice to see you again,

Hi!

> What do you mean with “to the next machine number in the type” ? That
> this may not advance in some case ?

The manual talks about machine numbers which, as I understand it, are
the mathematical values which are precisely represented by the fixed
point type. In my case they are the multiples of 2**(-11).

In my first (less informed?) attempt I used Angle_Type'Delta like this:

Angle := Angle + Angle_Type'Delta;

However, the distance between the represented values (the "machine
numbers") is not Delta, but rather Small. I suppose it wouldn't matter
much because the resulting value would "snap to" a machine number when
assigned to Angle. Well, I think.

> If the matter is the precise exploration of a precise set of points in a
> range, I may have a silly suggestion (silly in some sense, while not so
> much in some others) : why not use an array of predefined points ? Here,
> you would have an array of 12566 points. Ok, this may seems a big array,
> some design for hight efficiency.

I need to do real number computations on a microcontroller without a
floating point unit. I believe the various numeric quantities that I
need can be normalized into fairly narrow ranges so it seemed to me that
this is a perfect application of fixed point types. The compiler stores
the numbers as integers representing the appropriate multiple of Small.

I'm not using GNAT on the microcontroller but if the Ada compiler I am
using does the same thing as GNAT it will be able to fit Angle_Type as
it is currently defined into a 16 bit word and compute with it using
integer instructions. In my environment that is essential.

At the moment I'm looking at implementing some basic trig functions such
as Sine and Cosine taking Angle_Type parameters. My test program
compares the computed results against the much higher precision values
from GNAT's normal numeric library. I can thus assess the overall
accuracy of my implementation. I want to check every possible Angle_Type
value to be sure there are no surprises. For example right now I get
Constraint_Error when I attempt to compute the Sine of Angle_Type'First.
This is apparently because Angle_Type'First is actually slightly less
than -Pi and my simplistic implementation can't cope with that.

Peter

BTW, I will probably need a smaller delta than 0.0005 eventually (I
think). But I imagine changing that will be easy enough once I
understand what I'm doing. Alas, using too small a delta will probably
force the compiler to use 32 bits to store an Angle_Type value and
that's an undesirable thing on my machine.



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: Question about ordinary fixed point types.
  2010-08-16  1:03   ` Peter C. Chapin
@ 2010-08-16  4:11     ` Jeffrey Carter
  2010-08-16 10:03       ` Ludovic Brenta
  2010-08-16 11:31       ` Peter C. Chapin
  2010-08-16  9:23     ` Simon Wright
  1 sibling, 2 replies; 28+ messages in thread
From: Jeffrey Carter @ 2010-08-16  4:11 UTC (permalink / raw)


On 08/15/2010 06:03 PM, Peter C. Chapin wrote:
>
> In my first (less informed?) attempt I used Angle_Type'Delta like this:
>
> Angle := Angle + Angle_Type'Delta;
>
> However, the distance between the represented values (the "machine
> numbers") is not Delta, but rather Small. I suppose it wouldn't matter
> much because the resulting value would "snap to" a machine number when
> assigned to Angle. Well, I think.

Consider this example, which I 1st encountered in 1984:

with Ada.Text_IO;

procedure Fixed_Test is
    type Money is delta 0.01 range -100.0 .. 100.0;

    Cent : constant Money := Money'Delta;

    Change : Money := 0.0;
begin -- Fixed_Test
    Sum : for I in 1 .. 5 loop
       Change := Change + Cent;
    end loop Sum;

    Ada.Text_IO.Put_Line (Item => Money'Image (Change) );
end Fixed_Test;

Typically, the 'Small will be 2#0.000_000_1#, and the program will output 0.04. 
The program adds the machine number closest to 'Delta (which is 'Small) each 
time, not 'Delta, so there's no "snapping" taking place, except in the 
conversion of 0.01 to a machine number of type Money.

> I need to do real number computations on a microcontroller without a
> floating point unit. I believe the various numeric quantities that I
> need can be normalized into fairly narrow ranges so it seemed to me that
> this is a perfect application of fixed point types. The compiler stores
> the numbers as integers representing the appropriate multiple of Small.

That is a reason for the existence of fixed-point types.

> I'm not using GNAT on the microcontroller but if the Ada compiler I am
> using does the same thing as GNAT it will be able to fit Angle_Type as
> it is currently defined into a 16 bit word and compute with it using
> integer instructions. In my environment that is essential.

You can always say

for Angle_Value'Size use 16;

-- 
Jeff Carter
"Son of a window-dresser."
Monty Python & the Holy Grail
12

--- news://freenews.netfront.net/ - complaints: news@netfront.net ---



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: Question about ordinary fixed point types.
  2010-08-16  0:46   ` Peter C. Chapin
@ 2010-08-16  4:13     ` Jeffrey Carter
  2010-08-16  8:57       ` Simon Wright
  0 siblings, 1 reply; 28+ messages in thread
From: Jeffrey Carter @ 2010-08-16  4:13 UTC (permalink / raw)


On 08/15/2010 05:46 PM, Peter C. Chapin wrote:
>
> Probably I should use extra digits in the definition of the range to
> communicate my intentions to the compiler more precisely. Thus
>
> type Angle_Type is delta 0.0005 range -3.1415926535 .. 3.1415926535;

Why not use Ada.Numerics.Pi?

-- 
Jeff Carter
"Son of a window-dresser."
Monty Python & the Holy Grail
12

--- news://freenews.netfront.net/ - complaints: news@netfront.net ---



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: Question about ordinary fixed point types.
  2010-08-16  4:13     ` Jeffrey Carter
@ 2010-08-16  8:57       ` Simon Wright
  0 siblings, 0 replies; 28+ messages in thread
From: Simon Wright @ 2010-08-16  8:57 UTC (permalink / raw)


Jeffrey Carter <spam.jrcarter.not@spam.not.acm.org> writes:

> On 08/15/2010 05:46 PM, Peter C. Chapin wrote:
>>
>> Probably I should use extra digits in the definition of the range to
>> communicate my intentions to the compiler more precisely. Thus
>>
>> type Angle_Type is delta 0.0005 range -3.1415926535 .. 3.1415926535;
>
> Why not use Ada.Numerics.Pi?

We had a problem where a subcontractor had defined pi to be 3.14159
.. not quite good enough for a 32-bit Float.



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: Question about ordinary fixed point types.
  2010-08-16  1:03   ` Peter C. Chapin
  2010-08-16  4:11     ` Jeffrey Carter
@ 2010-08-16  9:23     ` Simon Wright
  2010-08-16 15:47       ` Simon Wright
  2010-08-17 14:37       ` sjw
  1 sibling, 2 replies; 28+ messages in thread
From: Simon Wright @ 2010-08-16  9:23 UTC (permalink / raw)


"Peter C. Chapin" <chapinp@acm.org> writes:

> I need to do real number computations on a microcontroller without a
> floating point unit. I believe the various numeric quantities that I
> need can be normalized into fairly narrow ranges so it seemed to me that
> this is a perfect application of fixed point types. The compiler stores
> the numbers as integers representing the appropriate multiple of Small.
>
> I'm not using GNAT on the microcontroller but if the Ada compiler I am
> using does the same thing as GNAT it will be able to fit Angle_Type as
> it is currently defined into a 16 bit word and compute with it using
> integer instructions. In my environment that is essential.

It would be very normal in that sort of environment to work in binary
fractions of 180 degrees.

with Ada.Numerics;
with Ada.Text_IO; use Ada.Text_IO;
procedure Angles is
   Angle_Type_Delta : constant := Ada.Numerics.Pi * 2.0 ** (-16);
   type Angle_Type is
     delta Angle_Type_Delta
       range -Ada.Numerics.Pi / 2 .. Ada.Numerics.Pi / 2;
   for Angle_Type'Small use Angle_Type_Delta;
   for Angle_Type'Size use 16;
   Count_Of_Values : Positive;
   Value : Angle_Type;
begin
   Put_Line ("angle_type'first: "
               & Long_Float'Image (Long_Float (Angle_Type'First)));
   Put_Line ("angle_type'last: "
               & Long_Float'Image (Long_Float (Angle_Type'Last)));
   Value := Angle_Type'First;
   Count_Of_Values := 1;
   loop
      exit when Value = Angle_Type'Last;
      Count_Of_Values := Count_Of_Values + 1;
      Value := Value + Angle_Type'Small;
   end loop;
   Put_Line ("count_of_values: " & Positive'Image (Count_Of_Values));
end Angles;

$ ./angles 
angle_type'first: -1.57079632679490E+00
angle_type'last:  1.57074838989528E+00
count_of_values:  65536



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: Question about ordinary fixed point types.
  2010-08-16  4:11     ` Jeffrey Carter
@ 2010-08-16 10:03       ` Ludovic Brenta
  2010-08-17 14:35         ` sjw
  2010-08-16 11:31       ` Peter C. Chapin
  1 sibling, 1 reply; 28+ messages in thread
From: Ludovic Brenta @ 2010-08-16 10:03 UTC (permalink / raw)


Jeffrey Carter wrote on comp.lang.ada:
> Consider this example, which I 1st encountered in 1984:
>
> with Ada.Text_IO;
>
> procedure Fixed_Test is
>     type Money is delta 0.01 range -100.0 .. 100.0;
>
>     Cent : constant Money := Money'Delta;
>
>     Change : Money := 0.0;
> begin -- Fixed_Test
>     Sum : for I in 1 .. 5 loop
>        Change := Change + Cent;
>     end loop Sum;
>
>     Ada.Text_IO.Put_Line (Item => Money'Image (Change) );
> end Fixed_Test;
>
> Typically, the 'Small will be 2#0.000_000_1#, and the program will output 0.04.
> The program adds the machine number closest to 'Delta (which is 'Small) each
> time, not 'Delta, so there's no "snapping" taking place, except in the
> conversion of 0.01 to a machine number of type Money.

Money is quite special; this is an area where approximation of a one
cent to a power of two is not acceptable. Ada has decimal fixed-point
types for this purpose.

More generally, Ada allows the programmer to specify the 'Small with
an attribute definition clause, so theoretically the exact solution to
Peter's problem would be:

Epsilon : constant := Ada.Numerics.Pi / 2 ** 15;
type Angle is delta Epsilon range -Ada.Numerics.Pi .. Ada.Numerics.Pi;
for Angle'Small use Epsilon;

This would, in theory, create the desired mapping from the integer
range [-2**15 .. 2**15] to the real range [-Pi .. Pi] without wasting
any machine numbers.

However and unfortunately, ARM 3.5.9(21) allows an implementation to
reject any 'Small that is not a power of two (and, in particular,
decimal fixed-point types). I'm not sure whether GNAT supports
arbitrary Smalls; from the doc, it seems that it actually rounds them
down to a power of two no smaller than 2**(-63).

--
Ludovic Brenta.



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: Question about ordinary fixed point types.
  2010-08-15 21:43 Question about ordinary fixed point types Peter C. Chapin
  2010-08-15 21:55 ` Shark8
  2010-08-15 22:08 ` Yannick Duchêne (Hibou57)
@ 2010-08-16 11:02 ` Stephen Leake
  2010-08-16 11:29   ` Peter C. Chapin
  2010-08-20  1:21 ` Yannick Duchêne (Hibou57)
  3 siblings, 1 reply; 28+ messages in thread
From: Stephen Leake @ 2010-08-16 11:02 UTC (permalink / raw)


"Peter C. Chapin" <chapinp@acm.org> writes:

> I have a need to work with ordinary fixed point types. I've read the in
> the reference manual about them (section 3.5.9, for example), and some
> other things. I still have a few questions. I thought I'd start with one
> here.
>
> Consider this example:
>
>
> type Angle_Type is delta 0.0005 range -3.1416 .. 3.1416;
> Angle : Angle_Type;

Why do you not specify:

for Angle_Type'small use 0.0005;

?

Then machine numbers will be multiples of 0.0005.

I've never used a fixed point type where I did not do this.

-- 
-- Stephe



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: Question about ordinary fixed point types.
  2010-08-16 11:02 ` Stephen Leake
@ 2010-08-16 11:29   ` Peter C. Chapin
  2010-08-16 12:53     ` Dmitry A. Kazakov
                       ` (3 more replies)
  0 siblings, 4 replies; 28+ messages in thread
From: Peter C. Chapin @ 2010-08-16 11:29 UTC (permalink / raw)


On 2010-08-16 07:02, Stephen Leake wrote:

>> type Angle_Type is delta 0.0005 range -3.1416 .. 3.1416;
>> Angle : Angle_Type;
> 
> Why do you not specify:
> 
> for Angle_Type'small use 0.0005;

I don't think I'm too concerned about the actual value of Small used. In
fact, I'd like to let the compiler choose so that it can optimize the
code better. Isn't it the case that using a power of two allows for more
efficient code generation for certain mathematical operations? I'm not
sure, but I seem to recall reading that somewhere. If that is true, then
I want that. My machine isn't very fast.

My original question wasn't about how to force the type to use a Small
that I want, rather it was about how can I be sure to visit every value
of the type in a loop for test purposes.

Peter



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: Question about ordinary fixed point types.
  2010-08-16  4:11     ` Jeffrey Carter
  2010-08-16 10:03       ` Ludovic Brenta
@ 2010-08-16 11:31       ` Peter C. Chapin
  1 sibling, 0 replies; 28+ messages in thread
From: Peter C. Chapin @ 2010-08-16 11:31 UTC (permalink / raw)


On 2010-08-16 00:11, Jeffrey Carter wrote:

> Consider this example, which I 1st encountered in 1984:
> 
> with Ada.Text_IO;
> 
> procedure Fixed_Test is
>    type Money is delta 0.01 range -100.0 .. 100.0;
> 
>    Cent : constant Money := Money'Delta;
> 
>    Change : Money := 0.0;
> begin -- Fixed_Test
>    Sum : for I in 1 .. 5 loop
>       Change := Change + Cent;
>    end loop Sum;
> 
>    Ada.Text_IO.Put_Line (Item => Money'Image (Change) );
> end Fixed_Test;
> 
> Typically, the 'Small will be 2#0.000_000_1#, and the program will
> output 0.04. The program adds the machine number closest to 'Delta
> (which is 'Small) each time, not 'Delta, so there's no "snapping" taking
> place, except in the conversion of 0.01 to a machine number of type Money.

The use of Small instead of Delta is the "snapping" I was talking about.
That is, despite the fact that you ask for Money'Delta you end up
advancing Change by Money'Small in your loop.

In my case advancing by Small is the effect I'm after so my earlier loop
where I was adding in Delta each time would have probably still worked
reliably.

Peter



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: Question about ordinary fixed point types.
  2010-08-16 11:29   ` Peter C. Chapin
@ 2010-08-16 12:53     ` Dmitry A. Kazakov
  2010-08-16 20:28       ` Peter C. Chapin
  2010-08-16 13:01     ` Dmitry A. Kazakov
                       ` (2 subsequent siblings)
  3 siblings, 1 reply; 28+ messages in thread
From: Dmitry A. Kazakov @ 2010-08-16 12:53 UTC (permalink / raw)


On Mon, 16 Aug 2010 07:29:13 -0400, Peter C. Chapin wrote:

> My original question wasn't about how to force the type to use a Small
> that I want, rather it was about how can I be sure to visit every value
> of the type in a loop for test purposes.

   type Angle_Type is delta 0.0005 range -3.1416 .. 3.1416;
   Angle : Angle_Type;
begin
   Angle := Angle_Type'First;
   while Angle < Angle_Type'Last loop
      ... -- Work with Angle here.
      Angle := Angle_Type'Succ (Angle);
   end loop;

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: Question about ordinary fixed point types.
  2010-08-16 11:29   ` Peter C. Chapin
  2010-08-16 12:53     ` Dmitry A. Kazakov
@ 2010-08-16 13:01     ` Dmitry A. Kazakov
  2010-08-16 14:28     ` Robert A Duff
  2010-08-17  2:03     ` Stephen Leake
  3 siblings, 0 replies; 28+ messages in thread
From: Dmitry A. Kazakov @ 2010-08-16 13:01 UTC (permalink / raw)


On Mon, 16 Aug 2010 07:29:13 -0400, Peter C. Chapin wrote:

>  how can I be sure to visit every value
> of the type in a loop for test purposes.

BTW, in your example you don't visit the last value. Should be:

   Angle := Angle_Type'First;
   loop
      ...
      exit when Angle = Angle_Type'Last;
      Angle := Angle_Type'Succ (Angle);
    end loop;

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: Question about ordinary fixed point types.
  2010-08-16 11:29   ` Peter C. Chapin
  2010-08-16 12:53     ` Dmitry A. Kazakov
  2010-08-16 13:01     ` Dmitry A. Kazakov
@ 2010-08-16 14:28     ` Robert A Duff
  2010-08-16 20:31       ` Peter C. Chapin
  2010-08-17  2:03     ` Stephen Leake
  3 siblings, 1 reply; 28+ messages in thread
From: Robert A Duff @ 2010-08-16 14:28 UTC (permalink / raw)


"Peter C. Chapin" <chapinp@acm.org> writes:

> I don't think I'm too concerned about the actual value of Small used. In
> fact, I'd like to let the compiler choose so that it can optimize the
> code better. Isn't it the case that using a power of two allows for more
> efficient code generation for certain mathematical operations? I'm not
> sure, but I seem to recall reading that somewhere. If that is true, then
> I want that. My machine isn't very fast.

I'd expect "*" and "/" to be faster for binary smalls,
but I don't think it makes any difference for "+" and "-".
Multiplying angles by angles doesn't make much sense...

> My original question wasn't about how to force the type to use a Small
> that I want, rather it was about how can I be sure to visit every value
> of the type in a loop for test purposes.

You can test your test.  That is, write the loop using the
advice elsewhere in this thread, and unchecked-convert
each value to an integer of the same size, and see if
you get the integer representations you are expecting.

By the way, Ada.Numerics.Pi has at least 51 digits.

- Bob



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: Question about ordinary fixed point types.
  2010-08-16  9:23     ` Simon Wright
@ 2010-08-16 15:47       ` Simon Wright
  2010-08-17 14:37       ` sjw
  1 sibling, 0 replies; 28+ messages in thread
From: Simon Wright @ 2010-08-16 15:47 UTC (permalink / raw)


Simon Wright <simon@pushface.org> writes:

> It would be very normal in that sort of environment to work in binary
> fractions of 180 degrees.

Unless of course your hardware works in increments of 0.0005 pi?



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: Question about ordinary fixed point types.
  2010-08-16 12:53     ` Dmitry A. Kazakov
@ 2010-08-16 20:28       ` Peter C. Chapin
  2010-08-16 20:58         ` Adam Beneschan
  0 siblings, 1 reply; 28+ messages in thread
From: Peter C. Chapin @ 2010-08-16 20:28 UTC (permalink / raw)


On 2010-08-16 08:53, Dmitry A. Kazakov wrote:

>    type Angle_Type is delta 0.0005 range -3.1416 .. 3.1416;
>    Angle : Angle_Type;
> begin
>    Angle := Angle_Type'First;
>    while Angle < Angle_Type'Last loop
>       ... -- Work with Angle here.
>       Angle := Angle_Type'Succ (Angle);
>    end loop;

That's cool. I didn't realize I could use Succ with a fixed point type.
I thought that was only for discrete types... or is a fixed point type a
kind of discrete type (it would make sense for it to be). I guess I can
look that one up. :)

Peter




^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: Question about ordinary fixed point types.
  2010-08-16 14:28     ` Robert A Duff
@ 2010-08-16 20:31       ` Peter C. Chapin
  2010-08-16 23:01         ` Robert A Duff
  0 siblings, 1 reply; 28+ messages in thread
From: Peter C. Chapin @ 2010-08-16 20:31 UTC (permalink / raw)


On 2010-08-16 10:28, Robert A Duff wrote:

> I'd expect "*" and "/" to be faster for binary smalls,
> but I don't think it makes any difference for "+" and "-".
> Multiplying angles by angles doesn't make much sense...

Probably true. On the other hand I anticipate needing other fixed point
types before I'm done so I think it would serve me well to get used to
using binary smalls.

> You can test your test.  That is, write the loop using the
> advice elsewhere in this thread, and unchecked-convert
> each value to an integer of the same size, and see if
> you get the integer representations you are expecting.

I might try that for interest's sake. If I understand you properly, I'd
have to (re)run that test for each implementation that I use. Of course,
I'm not really using very many implementations (just two).

Peter



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: Question about ordinary fixed point types.
  2010-08-16 20:28       ` Peter C. Chapin
@ 2010-08-16 20:58         ` Adam Beneschan
  0 siblings, 0 replies; 28+ messages in thread
From: Adam Beneschan @ 2010-08-16 20:58 UTC (permalink / raw)


On Aug 16, 1:28 pm, "Peter C. Chapin" <chap...@acm.org> wrote:
> On 2010-08-16 08:53, Dmitry A. Kazakov wrote:
>
> >    type Angle_Type is delta 0.0005 range -3.1416 .. 3.1416;
> >    Angle : Angle_Type;
> > begin
> >    Angle := Angle_Type'First;
> >    while Angle < Angle_Type'Last loop
> >       ... -- Work with Angle here.
> >       Angle := Angle_Type'Succ (Angle);
> >    end loop;
>
> That's cool. I didn't realize I could use Succ with a fixed point type.
> I thought that was only for discrete types... or is a fixed point type a
> kind of discrete type (it would make sense for it to be). I guess I can
> look that one up. :)

It's not a discrete type.  However, starting with Ada 95, 'Pred and
'Succ have been defined for fixed-point and floating-point types.  For
fixed-point types, 'Succ is defined to have the same result as adding
the 'Small of the type.  3.5(22-24).

                             -- Adam




^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: Question about ordinary fixed point types.
  2010-08-16 20:31       ` Peter C. Chapin
@ 2010-08-16 23:01         ` Robert A Duff
  2010-08-16 23:17           ` Peter C. Chapin
  0 siblings, 1 reply; 28+ messages in thread
From: Robert A Duff @ 2010-08-16 23:01 UTC (permalink / raw)


"Peter C. Chapin" <chapinp@acm.org> writes:

> On 2010-08-16 10:28, Robert A Duff wrote:
>
>> I'd expect "*" and "/" to be faster for binary smalls,
>> but I don't think it makes any difference for "+" and "-".
>> Multiplying angles by angles doesn't make much sense...
>
> Probably true. On the other hand I anticipate needing other fixed point
> types before I'm done so I think it would serve me well to get used to
> using binary smalls.

Well, you can use binary smalls when that makes sense -- it doesn't
mean you have to get used to using them when it doesn't.  For
calculations involving money, for example, you should look at
decimal fixed point types ("type ... is delta ... digits ...").

>> You can test your test.  That is, write the loop using the
>> advice elsewhere in this thread, and unchecked-convert
>> each value to an integer of the same size, and see if
>> you get the integer representations you are expecting.
>
> I might try that for interest's sake. If I understand you properly, I'd
> have to (re)run that test for each implementation that I use.

Can't hurt.  But I was more suggesting that such a test would
confirm your understanding of things like Fixed'Succ
and X := X + Fixed'Small.  Especially at the end-points
of the range, where fixed point type decls do something
weird (and undesirable, IMHO).

>...Of course,
> I'm not really using very many implementations (just two).

Which ones?  (Just curious.)

- Bob



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: Question about ordinary fixed point types.
  2010-08-16 23:01         ` Robert A Duff
@ 2010-08-16 23:17           ` Peter C. Chapin
  2010-08-17  0:56             ` Robert A Duff
  0 siblings, 1 reply; 28+ messages in thread
From: Peter C. Chapin @ 2010-08-16 23:17 UTC (permalink / raw)


On 2010-08-16 19:01, Robert A Duff wrote:

>> ...Of course,
>> I'm not really using very many implementations (just two).
> 
> Which ones?  (Just curious.)

GNAT and also the Ada Magic front end that outputs C from Ada 95 source.

Peter



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: Question about ordinary fixed point types.
  2010-08-16 23:17           ` Peter C. Chapin
@ 2010-08-17  0:56             ` Robert A Duff
  0 siblings, 0 replies; 28+ messages in thread
From: Robert A Duff @ 2010-08-17  0:56 UTC (permalink / raw)


"Peter C. Chapin" <chapinp@acm.org> writes:

> On 2010-08-16 19:01, Robert A Duff wrote:
>
>>> ...Of course,
>>> I'm not really using very many implementations (just two).
>> 
>> Which ones?  (Just curious.)
>
> GNAT and also the Ada Magic front end that outputs C from Ada 95 source.

OK, thanks, interesting.

I've done some work on both of those Ada compilers, but nothing in
the fixed-point-types area on either one.

- Bob



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: Question about ordinary fixed point types.
  2010-08-16 11:29   ` Peter C. Chapin
                       ` (2 preceding siblings ...)
  2010-08-16 14:28     ` Robert A Duff
@ 2010-08-17  2:03     ` Stephen Leake
  3 siblings, 0 replies; 28+ messages in thread
From: Stephen Leake @ 2010-08-17  2:03 UTC (permalink / raw)


"Peter C. Chapin" <chapinp@acm.org> writes:

> On 2010-08-16 07:02, Stephen Leake wrote:
>
>>> type Angle_Type is delta 0.0005 range -3.1416 .. 3.1416;
>>> Angle : Angle_Type;
>> 
>> Why do you not specify:
>> 
>> for Angle_Type'small use 0.0005;
>
> I don't think I'm too concerned about the actual value of Small used. In
> fact, I'd like to let the compiler choose so that it can optimize the
> code better. Isn't it the case that using a power of two allows for more
> efficient code generation for certain mathematical operations? 

Marginally. The representation is an integer with a scale = 1 /
angle_type'small. The scale is only used when converting to other
numeric types.

> I'm not sure, but I seem to recall reading that somewhere. If that is
> true, then I want that. My machine isn't very fast.

Get it logical first, then optimize.

> My original question wasn't about how to force the type to use a Small
> that I want, rather it was about how can I be sure to visit every value
> of the type in a loop for test purposes.

Then you need to make the loop step by 'Small.

-- 
-- Stephe



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: Question about ordinary fixed point types.
  2010-08-16 10:03       ` Ludovic Brenta
@ 2010-08-17 14:35         ` sjw
  2010-08-17 15:51           ` Ludovic Brenta
  0 siblings, 1 reply; 28+ messages in thread
From: sjw @ 2010-08-17 14:35 UTC (permalink / raw)


On Aug 16, 11:03 am, Ludovic Brenta <ludo...@ludovic-brenta.org>
wrote:

> However and unfortunately, ARM 3.5.9(21) allows an implementation to
> reject any 'Small that is not a power of two (and, in particular,
> decimal fixed-point types). I'm not sure whether GNAT supports
> arbitrary Smalls; from the doc, it seems that it actually rounds them
> down to a power of two no smaller than 2**(-63).

2**(-63)! That should be OK in this application, then.

The real question for Peter is, what does his target compiler do? If
it does as GNAT does and allows a delta and matching small of
ada.numerics.pi / 2 ** 15 then it makes sense to work in your scheme,
since literal values in the code and values for debug will be in
radians. If it only alows binary smalls, then (I would) work with
delta 2 ** (-15) range -1.0 .. 1.0, ie signed fractions of pi, and
apply the scaling factor as required.



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: Question about ordinary fixed point types.
  2010-08-16  9:23     ` Simon Wright
  2010-08-16 15:47       ` Simon Wright
@ 2010-08-17 14:37       ` sjw
  1 sibling, 0 replies; 28+ messages in thread
From: sjw @ 2010-08-17 14:37 UTC (permalink / raw)


On Aug 16, 10:23 am, Simon Wright <si...@pushface.org> wrote:
> "Peter C. Chapin" <chap...@acm.org> writes:
>
> > I need to do real number computations on a microcontroller without a
> > floating point unit. I believe the various numeric quantities that I
> > need can be normalized into fairly narrow ranges so it seemed to me that
> > this is a perfect application of fixed point types. The compiler stores
> > the numbers as integers representing the appropriate multiple of Small.
>
> > I'm not using GNAT on the microcontroller but if the Ada compiler I am
> > using does the same thing as GNAT it will be able to fit Angle_Type as
> > it is currently defined into a 16 bit word and compute with it using
> > integer instructions. In my environment that is essential.
>
> It would be very normal in that sort of environment to work in binary
> fractions of 180 degrees.
>
> with Ada.Numerics;
> with Ada.Text_IO; use Ada.Text_IO;
> procedure Angles is
>    Angle_Type_Delta : constant := Ada.Numerics.Pi * 2.0 ** (-16);
>    type Angle_Type is
>      delta Angle_Type_Delta
>        range -Ada.Numerics.Pi / 2 .. Ada.Numerics.Pi / 2;

Eep.

   Angle_Type_Delta : constant := Ada.Numerics.Pi * 2.0 ** (-15);
   type Angle_Type is
     delta Angle_Type_Delta
       range -Ada.Numerics.Pi .. Ada.Numerics.Pi;

>    for Angle_Type'Small use Angle_Type_Delta;
>    for Angle_Type'Size use 16;



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: Question about ordinary fixed point types.
  2010-08-17 14:35         ` sjw
@ 2010-08-17 15:51           ` Ludovic Brenta
  0 siblings, 0 replies; 28+ messages in thread
From: Ludovic Brenta @ 2010-08-17 15:51 UTC (permalink / raw)


sjw writes on comp.lang.ada:
> On Aug 16, 11:03 am, Ludovic Brenta <ludo...@ludovic-brenta.org>
> wrote:
>
>> However and unfortunately, ARM 3.5.9(21) allows an implementation to
>> reject any 'Small that is not a power of two (and, in particular,
>> decimal fixed-point types). I'm not sure whether GNAT supports
>> arbitrary Smalls; from the doc, it seems that it actually rounds them
>> down to a power of two no smaller than 2**(-63).
>
> 2**(-63)! That should be OK in this application, then.

Yes but I suspect it requires 64-bit hardware.  I don't think this would
work on a 16-bit microcontroller.

> The real question for Peter is, what does his target compiler do? If
> it does as GNAT does and allows a delta and matching small of
> ada.numerics.pi / 2 ** 15 then it makes sense to work in your scheme,
> since literal values in the code and values for debug will be in
> radians. If it only alows binary smalls, then (I would) work with
> delta 2 ** (-15) range -1.0 .. 1.0, ie signed fractions of pi, and
> apply the scaling factor as required.

Right.

-- 
Ludovic Brenta.



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: Question about ordinary fixed point types.
  2010-08-15 21:43 Question about ordinary fixed point types Peter C. Chapin
                   ` (2 preceding siblings ...)
  2010-08-16 11:02 ` Stephen Leake
@ 2010-08-20  1:21 ` Yannick Duchêne (Hibou57)
  3 siblings, 0 replies; 28+ messages in thread
From: Yannick Duchêne (Hibou57) @ 2010-08-20  1:21 UTC (permalink / raw)


Le Sun, 15 Aug 2010 23:43:43 +0200, Peter C. Chapin <chapinp@acm.org> a  
écrit:
> type Angle_Type is delta 0.0005 range -3.1416 .. 3.1416;
Does not solve the topic, but may be interesting in this area.
I have just noticed there is a GNAT warning option for this:

    gnatwb: turn on warnings for bad fixed value (not multiple of small)


^ permalink raw reply	[flat|nested] 28+ messages in thread

end of thread, other threads:[~2010-08-20  1:21 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-08-15 21:43 Question about ordinary fixed point types Peter C. Chapin
2010-08-15 21:55 ` Shark8
2010-08-16  0:46   ` Peter C. Chapin
2010-08-16  4:13     ` Jeffrey Carter
2010-08-16  8:57       ` Simon Wright
2010-08-15 22:08 ` Yannick Duchêne (Hibou57)
2010-08-16  1:03   ` Peter C. Chapin
2010-08-16  4:11     ` Jeffrey Carter
2010-08-16 10:03       ` Ludovic Brenta
2010-08-17 14:35         ` sjw
2010-08-17 15:51           ` Ludovic Brenta
2010-08-16 11:31       ` Peter C. Chapin
2010-08-16  9:23     ` Simon Wright
2010-08-16 15:47       ` Simon Wright
2010-08-17 14:37       ` sjw
2010-08-16 11:02 ` Stephen Leake
2010-08-16 11:29   ` Peter C. Chapin
2010-08-16 12:53     ` Dmitry A. Kazakov
2010-08-16 20:28       ` Peter C. Chapin
2010-08-16 20:58         ` Adam Beneschan
2010-08-16 13:01     ` Dmitry A. Kazakov
2010-08-16 14:28     ` Robert A Duff
2010-08-16 20:31       ` Peter C. Chapin
2010-08-16 23:01         ` Robert A Duff
2010-08-16 23:17           ` Peter C. Chapin
2010-08-17  0:56             ` Robert A Duff
2010-08-17  2:03     ` Stephen Leake
2010-08-20  1:21 ` Yannick Duchêne (Hibou57)

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