comp.lang.ada
 help / color / mirror / Atom feed
* Fixed-point question
@ 1995-04-01  0:00 Garlington KE
  1995-04-06  0:00 ` Robert Dewar
  0 siblings, 1 reply; 24+ messages in thread
From: Garlington KE @ 1995-04-01  0:00 UTC (permalink / raw)


There's probably a simple answer to this question, and I'm just too tired
to see it, but here goes anyway:

We have a user who has defined a fixed-point of the general form

   type A_Type is delta 0.1 range ...;

and some objects like the following:

   A: constant A_Type := 2.2;
   B: constant A_Type := 2.3;

and an abject C of A_Type which gets set to the expression 9.0 * 0.25.

He then runs the following code:

  if C = A then
     Text_IO.Put_Line("C equals A");
  elsif C = B then 
     Text_IO.Put_Line("C equals B"); 
  else
     Text_IO.Put_Line("C equals neither!");
  end if;

and of course it says that C equals neither, since C is stored as the
model number 2.25, which is neither 2.1875 nor 2.3125. I explain this
to the user, and all is well until he asks: "How should I do this
comparison, then?" Thinking back to my old FORTRAN days with floating-point,
I say, "Well, you compute the absolute difference between the two
numbers, and then see if the difference is less than some epsilon."
However, I can't for the life of me decide how to write the
equality function such that (1) C will be "equal" to B and (2) C will not
be "equal" to A, nor what epsilon is right (A_Type'Small?)

If someone could post the "roughly equal" function I'm describing, I would
appreciate it. (Note: this would need to be a pre-Ada 95 solution).

--------------------------------------------------------------------
Ken Garlington                  GarlingtonKE@lfwc.lockheed.com
F-22 Computer Resources         Lockheed Fort Worth Co.

If LFWC or the F-22 program has any opinions, they aren't telling me.




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

* Re: Fixed-point question
  1995-04-01  0:00 Fixed-point question Garlington KE
@ 1995-04-06  0:00 ` Robert Dewar
  1995-04-07  0:00   ` Garlington KE
  1995-04-07  0:00   ` Robert I. Eachus
  0 siblings, 2 replies; 24+ messages in thread
From: Robert Dewar @ 1995-04-06  0:00 UTC (permalink / raw)


I would tell this user not to use fixed-point. If people don't understand
that fixed-point is basically scaled integer I/O and can then figure out
things for themselves based on this, they will get confused.

On most modern machines floating-point is much faster than fixed-point in
any case. Was there really a good case for using fixed-point in this cas.





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

* Re: Fixed-point question
  1995-04-06  0:00 ` Robert Dewar
@ 1995-04-07  0:00   ` Garlington KE
  1995-04-07  0:00     ` Robert Dewar
  1995-04-07  0:00   ` Robert I. Eachus
  1 sibling, 1 reply; 24+ messages in thread
From: Garlington KE @ 1995-04-07  0:00 UTC (permalink / raw)


Robert Dewar (dewar@cs.nyu.edu) wrote:
: On most modern machines floating-point is much faster than fixed-point in
: any case. Was there really a good case for using fixed-point in this cas.

I don't know for sure, but I would assume space was the driver (16-bit
fixed-point vs. 32-bit fixed-point). Some of our users like to use fixed
point in large lookup tables to save space.

I've received a couple of replies concerning a "roughly equal" function,
and I think everyone so far ran up against the same snags I did. I haven't
had time to do any more work on this, but if I do, I'll post the results in
case anyone's interested.

To repeat the problem: A user declared a fixed-point type, like

   type D is delta 0.1 range ...

This generates a set of model numbers M. In this particular user's mind,
however, he is thinking in terms of the set S = { ... 2.0, 2.1, 2.2 ... }
(is there a name in Ada for this set?).

What happened was that he did a calculation that yielded the model number
2.25, which is neither the model number used by the compiler for the literal
2.2 nor the model number for the literal 2.3. What the user wants is a way
to map items in M to S, such that the model number for "2.1" will be
equal to 2.1, and both 2.25 and the model number for "2.3" will be equal to
"2.3". This "roughly equal" function would, ideally, be insensitve to the
order of the operands.

If all else fails, I could ask Tartan: their AdaScope debugger does this
mapping, such that when X = 2.25, asking the debugger to print out X yields
the value "2.3". (This also helped to confuse the user; his code was
operating as if X /= 2.3, but the debugger told him X was 2.3!)

--------------------------------------------------------------------
Ken Garlington                  GarlingtonKE@lfwc.lockheed.com
F-22 Computer Resources         Lockheed Fort Worth Co.

If LFWC or the F-22 program has any opinions, they aren't telling me.




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

* Re: Fixed-point question
  1995-04-06  0:00 ` Robert Dewar
  1995-04-07  0:00   ` Garlington KE
@ 1995-04-07  0:00   ` Robert I. Eachus
  1995-04-07  0:00     ` Robert Dewar
  1 sibling, 1 reply; 24+ messages in thread
From: Robert I. Eachus @ 1995-04-07  0:00 UTC (permalink / raw)


In article <3m43ot$grt@butch.lmsc.lockheed.com> l107353@cliffy.lfwc.lockheed.com (Garlington KE) writes:

 > Robert Dewar (dewar@cs.nyu.edu) wrote:
 > : On most modern machines floating-point is much faster than fixed-point in
 > : any case. Was there really a good case for using fixed-point in this cas.

   I beg to differ with Professor Dewar on this.  Especially when
32-bit fixed point can be used in preference to 64-bit floating point,
the costs of the added memory accesses dominates...  But even when it
is 32-bits vs. 32-bits, the added costs on processors like the Pentium
can tip the scales.

   However, if you need to do multiplies and divides on some RISC
chips, especially older SPARC implementations, the lack of support for
integer multiply and divide dominates.

 > I've received a couple of replies concerning a "roughly equal" function,
 > and I think everyone so far ran up against the same snags I did. I haven't
 > had time to do any more work on this, but if I do, I'll post the results in
 > case anyone's interested.

   There is no need of a "roughly equal" function with fixed point.
Numbers are either equal or they differ by 'SMALL or greater in both
Ada 83 and Ada 95.

  > To repeat the problem: A user declared a fixed-point type, like

  >   type D is delta 0.1 range ...

  Without a clause defining D'SMALL, D'SMALL is 1/16 (0.0625).

  > This generates a set of model numbers M. In this particular user's mind,
  > however, he is thinking in terms of the set S = { ... 2.0, 2.1, 2.2 ... }
  > (is there a name in Ada for this set?).

  The default display values?  (As far as I know there is no name for
the value set in the programmer's mind.  There might be a name for the
values produced by Text_IO.Fixed_IO.Put.)  The value set {... 2.0,
2.0625, 2.125, 2.1875, ...} is called the model numbers, and is
required to be identical--with the possible exception of one value at
each end if the specified limits are not model mnumbers--on all
compilers.  (The value set for the base type, however, may vary widely
in range from machine to machine or compiler to compiler.)

 > What happened was that he did a calculation that yielded the model
 > number 2.25, which is neither the model number used by the compiler
 > for the literal 2.2 nor the model number for the literal 2.3. What
 > the user wants is a way to map items in M to S, such that the model
 > number for "2.1" will be equal to 2.1, and both 2.25 and the model
 > number for "2.3" will be equal to "2.3". This "roughly equal"
 > function would, ideally, be insensitve to the order of the
 > operands.

   Yes, 2.25 is a model number, as is 2.3125...   The fix of course is
to either use Ada 95 decimal types, or a size clause which sets
D'SMALL to 0.1.

 > If all else fails, I could ask Tartan: their AdaScope debugger does this
 > mapping, such that when X = 2.25, asking the debugger to print out X yields
 > the value "2.3". (This also helped to confuse the user; his code was
 > operating as if X /= 2.3, but the debugger told him X was 2.3!)

   Uh, if they don't support size clauses for 'SMALL, or Ada 95
decimal types you have a problem.  You can use Get and Put on a String
to insure what you want, but it will be slow...

--

					Robert I. Eachus

with Standard_Disclaimer;
use  Standard_Disclaimer;
function Message (Text: in Clever_Ideas) return Better_Ideas is...




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

* Re: Fixed-point question
  1995-04-07  0:00   ` Garlington KE
@ 1995-04-07  0:00     ` Robert Dewar
  0 siblings, 0 replies; 24+ messages in thread
From: Robert Dewar @ 1995-04-07  0:00 UTC (permalink / raw)


Ken Garlington asks:

"   type D is delta 0.1 range ...

This generates a set of model numbers M. In this particular user's mind,
however, he is thinking in terms of the set S = { ... 2.0, 2.1, 2.2 ... }
(is there a name in Ada for this set?)."

No, there is no name for this set as the declaration stands. However, if
the user is thinking in terms of this set, then the following declaration
should be added (Ada 83 or Ada 95)

     for D'Small use 0.1;

then there *is* a name for that set, its called the set of model
numbers and things will work exactly as expected.

If your compiler rejects this declaration, it is being naughty and you
should complain to the vendor, there is no god excuse for not supporting
decimal small values.





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

* Re: Fixed-point question
  1995-04-07  0:00   ` Robert I. Eachus
@ 1995-04-07  0:00     ` Robert Dewar
  0 siblings, 0 replies; 24+ messages in thread
From: Robert Dewar @ 1995-04-07  0:00 UTC (permalink / raw)


On the Pentium, floating-point multiplication is faster than integer
multiplication, and this is a common pattern on modern RISC chips, where
the floating-point multiply is pipelined, but it is not considered worth
pipelining the integer multiply (and also, as I pointed out, you usually
have an extra shift for the fixed-point multiply).

As has been pointed out, there may be considerations of space in using
fixed-point, but there will be a time cost in the typical case.





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

* Fixed-point question
@ 2015-06-26 13:20 Patrick Noffke
  2015-06-26 16:56 ` Jeffrey R. Carter
  0 siblings, 1 reply; 24+ messages in thread
From: Patrick Noffke @ 2015-06-26 13:20 UTC (permalink / raw)


Why are C1 and C2 different?

with Ada.Text_IO;

procedure FP_Test is
   type Fixed_Type is delta 1.0 / 180.0 range 0.0 .. 65535.0 / 180.0;
   N : constant := 0.2;
   D : constant := 4.5 / 330.0;  -- 0.013636

   C1 : constant Fixed_Type := Fixed_Type (N / D);
   C2 : constant Fixed_Type := N / D;

begin
   Ada.Text_IO.Put_Line ("C1 := " & C1'Img);
   Ada.Text_IO.Put_Line ("C2 := " & C2'Img);
end FP_Test;

$ ./fp_test 
C1 :=  14.664
C2 :=  17.000

I am using GNAT on Fedora 21 (x86_64) and GNAT 2014 for ARM-ELF (Linux-hosted).  The output above is on Fedora.  In the ARM processor (Cortex-M4), C1 is 14.667 and C2 is 18.

It appears that for ARM, the compiler is computing C2 as Fixed_Type (N) / Fixed_Type (D), or 0.2 / (2 / 180) = 0.2 / 0.01111 = 18.

I'm not sure why C2 is 17 on the Fedora PC.

Thanks,
Patrick

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

* Re: Fixed-point question
  2015-06-26 13:20 Patrick Noffke
@ 2015-06-26 16:56 ` Jeffrey R. Carter
  2015-06-26 18:21   ` Patrick Noffke
  0 siblings, 1 reply; 24+ messages in thread
From: Jeffrey R. Carter @ 2015-06-26 16:56 UTC (permalink / raw)


On 06/26/2015 06:20 AM, Patrick Noffke wrote:
> 
>    type Fixed_Type is delta 1.0 / 180.0 range 0.0 .. 65535.0 / 180.0;

What is Fixed_Type'Small?

>    C1 : constant Fixed_Type := Fixed_Type (N / D);

What is C1'Size?

If you really want to use multiples of 1/180, you probably want to do

Delta_And_Small : constant := 1.0 / 180.0;

type Fixed_Type is delta Delta_And_Small range 0.0 .. 65535.0 * Delta_And_Small;
for Fixed_Type'Small use Delta_And_Small;

-- 
Jeff Carter
"I did not rob a bank. If I'd robbed a bank, everything
would be great. I tried to rob a bank, is what happened,
and they got me."
Take the Money and Run
139

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

* Re: Fixed-point question
  2015-06-26 16:56 ` Jeffrey R. Carter
@ 2015-06-26 18:21   ` Patrick Noffke
  2015-06-26 20:21     ` Anh Vo
                       ` (2 more replies)
  0 siblings, 3 replies; 24+ messages in thread
From: Patrick Noffke @ 2015-06-26 18:21 UTC (permalink / raw)


On Friday, June 26, 2015 at 11:56:44 AM UTC-5, Jeffrey R. Carter wrote:
> On 06/26/2015 06:20 AM, Patrick Noffke wrote:
> > 
> >    type Fixed_Type is delta 1.0 / 180.0 range 0.0 .. 65535.0 / 180.0;
> 
> What is Fixed_Type'Small?

It is 1/180.

> 
> >    C1 : constant Fixed_Type := Fixed_Type (N / D);
> 
> What is C1'Size?
> 
> If you really want to use multiples of 1/180, you probably want to do
> 
> Delta_And_Small : constant := 1.0 / 180.0;
> 
> type Fixed_Type is delta Delta_And_Small range 0.0 .. 65535.0 * Delta_And_Small;
> for Fixed_Type'Small use Delta_And_Small;
> 

I do that in my application.  I just did the above for a simple test case.  Doing as you suggest does not change the result on either platform.

Pat


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

* Re: Fixed-point question
  2015-06-26 18:21   ` Patrick Noffke
@ 2015-06-26 20:21     ` Anh Vo
  2015-06-26 20:25     ` Jeffrey R. Carter
  2015-06-26 23:14     ` Qun-Ying
  2 siblings, 0 replies; 24+ messages in thread
From: Anh Vo @ 2015-06-26 20:21 UTC (permalink / raw)


On Friday, June 26, 2015 at 11:22:00 AM UTC-7, Patrick Noffke wrote:
> On Friday, June 26, 2015 at 11:56:44 AM UTC-5, Jeffrey R. Carter wrote:
> > On 06/26/2015 06:20 AM, Patrick Noffke wrote:
> > > 
> > >    type Fixed_Type is delta 1.0 / 180.0 range 0.0 .. 65535.0 / 180.0;
> > 
> > What is Fixed_Type'Small?
> 
> It is 1/180.
> 
> > 
> > >    C1 : constant Fixed_Type := Fixed_Type (N / D);
> > 
> > What is C1'Size?
> > 
> > If you really want to use multiples of 1/180, you probably want to do
> > 
> > Delta_And_Small : constant := 1.0 / 180.0;
> > 
> > type Fixed_Type is delta Delta_And_Small range 0.0 .. 65535.0 * Delta_And_Small;
> > for Fixed_Type'Small use Delta_And_Small;
> > 
> 
> I do that in my application.  I just did the above for a simple test case.  Doing as you suggest does not change the result on either platform.
> 

It is time for a bug report. In fact, it occurs in other platforms as well. In addition, GNAT-GPL-2014 and GNAT Pro exhibit the same behavior.

Anh Vo

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

* Re: Fixed-point question
  2015-06-26 18:21   ` Patrick Noffke
  2015-06-26 20:21     ` Anh Vo
@ 2015-06-26 20:25     ` Jeffrey R. Carter
  2015-06-27  2:55       ` Patrick Noffke
  2015-06-26 23:14     ` Qun-Ying
  2 siblings, 1 reply; 24+ messages in thread
From: Jeffrey R. Carter @ 2015-06-26 20:25 UTC (permalink / raw)


On 06/26/2015 11:21 AM, Patrick Noffke wrote:
> On Friday, June 26, 2015 at 11:56:44 AM UTC-5, Jeffrey R. Carter wrote:
>> On 06/26/2015 06:20 AM, Patrick Noffke wrote:
>>>
>>>    type Fixed_Type is delta 1.0 / 180.0 range 0.0 .. 65535.0 / 180.0;
>>
>> What is Fixed_Type'Small?
> 
> It is 1/180.

Not as you wrote it. By default, the small of an ordinary fixed-point type is a
power of two <= the delta. In this case, that would be 2**(-8) or less [ARM
3.5.9 (8/2)].

The introduction to this I got (in Ada 83) was

Cent : constant := 0.01;

type Money is delta Cent range -10_000.0 .. 10_000.0;

Amount : Money := 0.0;

Add_5 : for I in 1 .. 5 loop
   Amount := Amount + Cent;
end loop Add_5;

Text_IO.Put_Line (Item => Money'Image (Amount) );

which output 0.04, to most people's consternation.

This is because the small was 2**(-7), or 1/128. The multiple of that nearest to
0.01 is 1/128, so Amount ends up containing 5/128, or 0.0390625. Adding

for Money'Small use Cent;

gives the expected result.

-- 
Jeff Carter
"I did not rob a bank. If I'd robbed a bank, everything
would be great. I tried to rob a bank, is what happened,
and they got me."
Take the Money and Run
139


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

* Re: Fixed-point question
  2015-06-26 18:21   ` Patrick Noffke
  2015-06-26 20:21     ` Anh Vo
  2015-06-26 20:25     ` Jeffrey R. Carter
@ 2015-06-26 23:14     ` Qun-Ying
  2015-06-27  3:00       ` Patrick Noffke
  2 siblings, 1 reply; 24+ messages in thread
From: Qun-Ying @ 2015-06-26 23:14 UTC (permalink / raw)


In my test with Linux x86_64 with FSF GNAT 4.9.2

C1 :=  14.664
C2 :=  17.000
Small :=  3.90625000000000000E-03
1/180 :=  5.55555555555555556E-03

With Jeffrey's changes I got:
C1 :=  14.667
C2 :=  18.000
Small :=  5.55555555555555556E-03
1/180 :=  5.55555555555555556E-03


Patrick Noffke wrote:
> On Friday, June 26, 2015 at 11:56:44 AM UTC-5, Jeffrey R. Carter wrote:
>> On 06/26/2015 06:20 AM, Patrick Noffke wrote:
>>>
>>>     type Fixed_Type is delta 1.0 / 180.0 range 0.0 .. 65535.0 / 180.0;
>>
>> What is Fixed_Type'Small?
>
> It is 1/180.
>
>>
>>>     C1 : constant Fixed_Type := Fixed_Type (N / D);
>>
>> What is C1'Size?
>>
>> If you really want to use multiples of 1/180, you probably want to do
>>
>> Delta_And_Small : constant := 1.0 / 180.0;
>>
>> type Fixed_Type is delta Delta_And_Small range 0.0 .. 65535.0 * Delta_And_Small;
>> for Fixed_Type'Small use Delta_And_Small;
>>
>
> I do that in my application.  I just did the above for a simple test case.  Doing as you suggest does not change the result on either platform.
>
> Pat
>



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

* Re: Fixed-point question
  2015-06-26 20:25     ` Jeffrey R. Carter
@ 2015-06-27  2:55       ` Patrick Noffke
  0 siblings, 0 replies; 24+ messages in thread
From: Patrick Noffke @ 2015-06-27  2:55 UTC (permalink / raw)


On Friday, June 26, 2015 at 3:25:17 PM UTC-5, Jeffrey R. Carter wrote:
> On 06/26/2015 11:21 AM, Patrick Noffke wrote:
> > On Friday, June 26, 2015 at 11:56:44 AM UTC-5, Jeffrey R. Carter wrote:
> >> On 06/26/2015 06:20 AM, Patrick Noffke wrote:
> >>>
> >>>    type Fixed_Type is delta 1.0 / 180.0 range 0.0 .. 65535.0 / 180.0;
> >>
> >> What is Fixed_Type'Small?
> > 
> > It is 1/180.
> 
> Not as you wrote it. 

You're right.  I now get 18.000 for C2 on my home PC (FSF GNAT 4.8.3) with your changes.  I'll check again tomorrow at work -- I probably forgot to recompile.

Thanks,
Pat

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

* Re: Fixed-point question
  2015-06-26 23:14     ` Qun-Ying
@ 2015-06-27  3:00       ` Patrick Noffke
  2015-06-27  4:44         ` Jeffrey R. Carter
  0 siblings, 1 reply; 24+ messages in thread
From: Patrick Noffke @ 2015-06-27  3:00 UTC (permalink / raw)


On Friday, June 26, 2015 at 6:13:11 PM UTC-5, qunying wrote:
> In my test with Linux x86_64 with FSF GNAT 4.9.2
> 
> C1 :=  14.664
> C2 :=  17.000
> Small :=  3.90625000000000000E-03
> 1/180 :=  5.55555555555555556E-03
> 
> With Jeffrey's changes I got:
> C1 :=  14.667
> C2 :=  18.000
> Small :=  5.55555555555555556E-03
> 1/180 :=  5.55555555555555556E-03
> 

So is this a bug, is the ARM not clear on what should happen here, or is it expected?

Pat

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

* Re: Fixed-point question
  2015-06-27  3:00       ` Patrick Noffke
@ 2015-06-27  4:44         ` Jeffrey R. Carter
  2015-06-27 17:59           ` Patrick Noffke
  0 siblings, 1 reply; 24+ messages in thread
From: Jeffrey R. Carter @ 2015-06-27  4:44 UTC (permalink / raw)


On 06/26/2015 08:00 PM, Patrick Noffke wrote:
> On Friday, June 26, 2015 at 6:13:11 PM UTC-5, qunying wrote:
>> In my test with Linux x86_64 with FSF GNAT 4.9.2
>>
>> C1 :=  14.664
>> C2 :=  17.000
>> Small :=  3.90625000000000000E-03
>> 1/180 :=  5.55555555555555556E-03
>>
>> With Jeffrey's changes I got:
>> C1 :=  14.667
>> C2 :=  18.000
>> Small :=  5.55555555555555556E-03
>> 1/180 :=  5.55555555555555556E-03
>>
> 
> So is this a bug, is the ARM not clear on what should happen here, or is it expected?

With a small of 1/180:

For C1, AFAICT, the compiler will calculate N/D exactly, getting 44/3 =
14.6666...., and then convert this to Fixed_type, getting 2640/180.

For C2, "/" for Fixed_Type is used, so N and D are converted to Fixed_Type
first. N = 0.2 = 36/180, and D = 0.013636... is closest to 2/180 = 0.0111...
(36/180)/(2/180) = 36/2 = 18.

Working out the expected result for the default small of 1/256 is left as an
exercise for the reader.

-- 
Jeff Carter
"I did not rob a bank. If I'd robbed a bank, everything
would be great. I tried to rob a bank, is what happened,
and they got me."
Take the Money and Run
139


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

* Re: Fixed-point question
  2015-06-27  4:44         ` Jeffrey R. Carter
@ 2015-06-27 17:59           ` Patrick Noffke
  2015-06-27 18:38             ` Jeffrey R. Carter
  0 siblings, 1 reply; 24+ messages in thread
From: Patrick Noffke @ 2015-06-27 17:59 UTC (permalink / raw)


On Friday, June 26, 2015 at 11:44:07 PM UTC-5, Jeffrey R. Carter wrote:
> On 06/26/2015 08:00 PM, Patrick Noffke wrote:
> > On Friday, June 26, 2015 at 6:13:11 PM UTC-5, qunying wrote:
> >> In my test with Linux x86_64 with FSF GNAT 4.9.2
> >>
> >> C1 :=  14.664
> >> C2 :=  17.000
> >> Small :=  3.90625000000000000E-03
> >> 1/180 :=  5.55555555555555556E-03
> >>
> >> With Jeffrey's changes I got:
> >> C1 :=  14.667
> >> C2 :=  18.000
> >> Small :=  5.55555555555555556E-03
> >> 1/180 :=  5.55555555555555556E-03
> >>
> > 
> > So is this a bug, is the ARM not clear on what should happen here, or is it expected?
> 
> With a small of 1/180:
> 
> For C1, AFAICT, the compiler will calculate N/D exactly, getting 44/3 =
> 14.6666...., and then convert this to Fixed_type, getting 2640/180.
> 
> For C2, "/" for Fixed_Type is used, so N and D are converted to Fixed_Type
> first. 

My question is whether this is the right thing for the compiler to do.

Pat


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

* Re: Fixed-point question
  2015-06-27 17:59           ` Patrick Noffke
@ 2015-06-27 18:38             ` Jeffrey R. Carter
  2015-06-27 19:20               ` Bob Duff
  2015-06-27 23:41               ` Anh Vo
  0 siblings, 2 replies; 24+ messages in thread
From: Jeffrey R. Carter @ 2015-06-27 18:38 UTC (permalink / raw)


On 06/27/2015 10:59 AM, Patrick Noffke wrote:
> On Friday, June 26, 2015 at 11:44:07 PM UTC-5, Jeffrey R. Carter wrote:
>>
>> With a small of 1/180:
>>
>> For C1, AFAICT, the compiler will calculate N/D exactly, getting 44/3 =
>> 14.6666...., and then convert this to Fixed_type, getting 2640/180.
>>
>> For C2, "/" for Fixed_Type is used, so N and D are converted to Fixed_Type
>> first. 
> 
> My question is whether this is the right thing for the compiler to do.

For C2, definitely. I'm not sure why the type conversion for C1 results in using
the universal-real operator.

-- 
Jeff Carter
"My brain hurts!"
Monty Python's Flying Circus
21


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

* Re: Fixed-point question
  2015-06-27 18:38             ` Jeffrey R. Carter
@ 2015-06-27 19:20               ` Bob Duff
  2015-06-27 19:57                 ` Jeffrey R. Carter
  2015-06-27 23:41               ` Anh Vo
  1 sibling, 1 reply; 24+ messages in thread
From: Bob Duff @ 2015-06-27 19:20 UTC (permalink / raw)


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

>...I'm not sure why the type conversion for C1 results in using
> the universal-real operator.

Because of RM-8.6(29).  Actually, it's the root_real operator;
universal_real has no operators.  Without the preference rule
of 8.6(29), it would be ambiguous.  As you said, it's calculating
an exact rational number (at compile time), and converting that.

- Bob


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

* Re: Fixed-point question
  2015-06-27 19:20               ` Bob Duff
@ 2015-06-27 19:57                 ` Jeffrey R. Carter
  2015-06-27 20:42                   ` Bob Duff
  0 siblings, 1 reply; 24+ messages in thread
From: Jeffrey R. Carter @ 2015-06-27 19:57 UTC (permalink / raw)


On 06/27/2015 12:20 PM, Bob Duff wrote:
> 
> Because of RM-8.6(29).  Actually, it's the root_real operator;
> universal_real has no operators.  Without the preference rule
> of 8.6(29), it would be ambiguous.  As you said, it's calculating
> an exact rational number (at compile time), and converting that.

Root_Real, right. I still tend to think in terms of the rules for Ada 83.

So for C1, the compiler is looking for a visible "/" that yields a result that
can be converted to Fixed_Type. These include those for at least Root_Real,
Float, Duration, and Fixed_Type. 8.6(29) results in Root_Real's "/" being selected.

For C2, the compiler is looking for a visible "/" that yields a result of
Fixed_Type, and only Fixed_Type's "/" does that.

Is that anything close to correct?

-- 
Jeff Carter
"My brain hurts!"
Monty Python's Flying Circus
21


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

* Re: Fixed-point question
  2015-06-27 19:57                 ` Jeffrey R. Carter
@ 2015-06-27 20:42                   ` Bob Duff
  2015-06-28 11:39                     ` Brian Drummond
  2015-06-29 13:28                     ` Patrick Noffke
  0 siblings, 2 replies; 24+ messages in thread
From: Bob Duff @ 2015-06-27 20:42 UTC (permalink / raw)


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

> Root_Real, right. I still tend to think in terms of the rules for Ada 83.

;-)

> So for C1, the compiler is looking for a visible "/" that yields a result that
> can be converted to Fixed_Type.

Close.  It's looking for a "/" that has two parameters that can be
converted from universal_real -- the two literals.  Or were they named
numbers (I forget)?  The result of those "/" ops can be anything,
because type conversions don't provide an expected type (i.e. the
expected type for the operand of a type conversion is "any type").

>...These include those for at least Root_Real,
> Float, Duration, and Fixed_Type. 8.6(29) results in Root_Real's "/" being selected.

Right.

> For C2, the compiler is looking for a visible "/" that yields a result of
> Fixed_Type, and only Fixed_Type's "/" does that.

Well, fixed-point division is kind of magical.  The individual
fixed-point types don't have a "/" that takes parameters of the type and
returns the same type, but there's a "/" on universal_fixed that can be
used on any fixed-point types, and the two operands and result can all
be of different fixed-point types.  See 4.5.5(18).  Similar for "*".
There are also mixed fixed-integer ops for each fixed-point type.

There's a rule somewhere that says the context has to provide
the type of the result, so the compiler knows how much precision
is needed.  E.g. you can say "X := Y * Z;" but not
"X := Y * Z * W;".

> Is that anything close to correct?

Yes, close enough to understand what the program does at run time,
although not quite close enough to write a correct Ada compiler.  ;-)

- Bob


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

* Re: Fixed-point question
  2015-06-27 18:38             ` Jeffrey R. Carter
  2015-06-27 19:20               ` Bob Duff
@ 2015-06-27 23:41               ` Anh Vo
  1 sibling, 0 replies; 24+ messages in thread
From: Anh Vo @ 2015-06-27 23:41 UTC (permalink / raw)


On Saturday, June 27, 2015 at 11:38:11 AM UTC-7, Jeffrey R. Carter wrote:
> On 06/27/2015 10:59 AM, Patrick Noffke wrote:
> > On Friday, June 26, 2015 at 11:44:07 PM UTC-5, Jeffrey R. Carter wrote:
> >>
> >> With a small of 1/180:
> >>
> >> For C1, AFAICT, the compiler will calculate N/D exactly, getting 44/3 =
> >> 14.6666...., and then convert this to Fixed_type, getting 2640/180.
> >>
> >> For C2, "/" for Fixed_Type is used, so N and D are converted to Fixed_Type
> >> first. 
> > 
> > My question is whether this is the right thing for the compiler to do.
> 
> For C2, definitely. I'm not sure why the type conversion for C1 results in using
> the universal-real operator. 

Because N and D are universal-real. In fact, if N and D are declared as Fixed_Type, C1 and C2 have the same value.

Anh Vo

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

* Re: Fixed-point question
  2015-06-27 20:42                   ` Bob Duff
@ 2015-06-28 11:39                     ` Brian Drummond
  2015-06-29 13:28                     ` Patrick Noffke
  1 sibling, 0 replies; 24+ messages in thread
From: Brian Drummond @ 2015-06-28 11:39 UTC (permalink / raw)


On Sat, 27 Jun 2015 16:42:07 -0400, Bob Duff wrote:

> There's a rule somewhere that says the context has to provide the type
> of the result, so the compiler knows how much precision is needed.  E.g.
> you can say "X := Y * Z;" but not "X := Y * Z * W;".

A rule that surprised me when I first ran into it, but on a moment's 
reflection as a hardware guy, makes perfect sense. It forces you to 
specify the range and resolution of intermediate results, eliminating 
rounding and overflow surprises.

Once I rewrote an algorithm along the lines imposed by this rule, I could 
make it generic and instantiate it with any fixed or floating point type 
I wanted, to investigate its stability and accuracy (with the eventual 
intent of translating to a VHDL implementation using minimal hardware).

-- Brian


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

* Re: Fixed-point question
  2015-06-27 20:42                   ` Bob Duff
  2015-06-28 11:39                     ` Brian Drummond
@ 2015-06-29 13:28                     ` Patrick Noffke
  2015-06-29 14:13                       ` Bob Duff
  1 sibling, 1 reply; 24+ messages in thread
From: Patrick Noffke @ 2015-06-29 13:28 UTC (permalink / raw)


On Saturday, June 27, 2015 at 3:42:11 PM UTC-5, Bob Duff wrote:
> > For C2, the compiler is looking for a visible "/" that yields a result of
> > Fixed_Type, and only Fixed_Type's "/" does that.
> 
> Well, fixed-point division is kind of magical.  The individual
> fixed-point types don't have a "/" that takes parameters of the type and
> returns the same type, but there's a "/" on universal_fixed that can be
> used on any fixed-point types, and the two operands and result can all
> be of different fixed-point types.  See 4.5.5(18).  Similar for "*".
> There are also mixed fixed-integer ops for each fixed-point type.
> 
> There's a rule somewhere that says the context has to provide
> the type of the result, so the compiler knows how much precision
> is needed.  E.g. you can say "X := Y * Z;" but not
> "X := Y * Z * W;".
> 

But for C2 why is the compiler implicitly converting N and D to universal_fixed before doing the division?  Isn't it just as valid to treat the constants as universal_real and use the root_real "/" operator first and then do the conversion?  I don't see this discussed in 8.6 (29).  There must be another rule for type conversion taking preference over division.

Thanks,
Patrick

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

* Re: Fixed-point question
  2015-06-29 13:28                     ` Patrick Noffke
@ 2015-06-29 14:13                       ` Bob Duff
  0 siblings, 0 replies; 24+ messages in thread
From: Bob Duff @ 2015-06-29 14:13 UTC (permalink / raw)


Patrick Noffke <patrick.noffke@gmail.com> writes:

> But for C2 why is the compiler implicitly converting N and D to universal_fixed
> before doing the division?  Isn't it just as valid to treat the constants as
> universal_real and use the root_real "/" operator first and then do the
> conversion?  I don't see this discussed in 8.6 (29).  There must be another
> rule for type conversion taking preference over division.

The "/" for root_real returns root_real, and there is no implicit
conversion from root_real to the fixed point type.  There is
an implicit conversion from universal_real (which is the type
of literals and named numbers) to any numeric type.

- Bob

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

end of thread, other threads:[~2015-06-29 14:13 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1995-04-01  0:00 Fixed-point question Garlington KE
1995-04-06  0:00 ` Robert Dewar
1995-04-07  0:00   ` Garlington KE
1995-04-07  0:00     ` Robert Dewar
1995-04-07  0:00   ` Robert I. Eachus
1995-04-07  0:00     ` Robert Dewar
  -- strict thread matches above, loose matches on Subject: below --
2015-06-26 13:20 Patrick Noffke
2015-06-26 16:56 ` Jeffrey R. Carter
2015-06-26 18:21   ` Patrick Noffke
2015-06-26 20:21     ` Anh Vo
2015-06-26 20:25     ` Jeffrey R. Carter
2015-06-27  2:55       ` Patrick Noffke
2015-06-26 23:14     ` Qun-Ying
2015-06-27  3:00       ` Patrick Noffke
2015-06-27  4:44         ` Jeffrey R. Carter
2015-06-27 17:59           ` Patrick Noffke
2015-06-27 18:38             ` Jeffrey R. Carter
2015-06-27 19:20               ` Bob Duff
2015-06-27 19:57                 ` Jeffrey R. Carter
2015-06-27 20:42                   ` Bob Duff
2015-06-28 11:39                     ` Brian Drummond
2015-06-29 13:28                     ` Patrick Noffke
2015-06-29 14:13                       ` Bob Duff
2015-06-27 23:41               ` Anh Vo

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