comp.lang.ada
 help / color / mirror / Atom feed
* Higher precision and generics
@ 1995-03-11 17:41 Duncan Sands
  1995-03-14 16:13 ` David Arno
  1995-03-15 15:36 ` Mats Weber
  0 siblings, 2 replies; 12+ messages in thread
From: Duncan Sands @ 1995-03-11 17:41 UTC (permalink / raw)


I am writing a package of matrix routines (in Ada!) in which some intermediate results
should be calculated in higher precision than normal.  The type for normal precision is
called Real and is a generic parameter of my package:
generic
   type Real is digits <>;
package Matrix_Stuff is
   ...
end;

In the body I would like to be able to declare Double to be a higher precision
floating point type, something like:
package body Matrix_Stuff is
   type Double is digits 2*Real'Digits;
   ...
end;

Unfortunately, this does not compile: apparently formal types like Real are not
considered static, so Real'Digits is not considered static, and only static
expressions are allowed in a "type X is digits expression" declaration.  (If
I write "type Double is digits 2*Float'Digits" then it compiles fine).

What can I do to get type Double to be of higher precision than Real?
Can anyone please help?  And does anyone know why formal types like Real are not
considered static?

Thanks a lot,

Duncan Sands.



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

* Re: Higher precision and generics
  1995-03-11 17:41 Higher precision and generics Duncan Sands
@ 1995-03-14 16:13 ` David Arno
  1995-03-15 12:12   ` Duncan Sands
  1995-03-15 15:36 ` Mats Weber
  1 sibling, 1 reply; 12+ messages in thread
From: David Arno @ 1995-03-14 16:13 UTC (permalink / raw)


In article <3jsnbf$ido@nef.ens.fr> sands@clipper.ens.fr "Duncan Sands" writes:

: I am writing a package of matrix routines (in Ada!) in which some intermediate
:  results
: should be calculated in higher precision than normal.  The type for normal
:  precision is
: called Real and is a generic parameter of my package:
: generic
:    type Real is digits <>;
: package Matrix_Stuff is
:    ...
: end;
: 
: In the body I would like to be able to declare Double to be a higher precision
: floating point type, something like:
: package body Matrix_Stuff is
:    type Double is digits 2*Real'Digits;
:    ...
: end;
: 
: Unfortunately, this does not compile: apparently formal types like Real are not
: considered static, so Real'Digits is not considered static, and only static
: expressions are allowed in a "type X is digits expression" declaration.  (If
: I write "type Double is digits 2*Float'Digits" then it compiles fine).
: 
: What can I do to get type Double to be of higher precision than Real?
: Can anyone please help?  And does anyone know why formal types like Real are not: considered static?
: 
: Thanks a lot,
: 
: Duncan Sands.
: 

Probably the best thing to do in this situation is to declare a type within
the package body which has the highest precision possible:

	type Max_Precision_type is digits System.Max_digits;

and to use that internaly. Even if there were a way of overcoming the need
for the expression after digits to be statis, the concept of your internal
one always being double the precision of the parameter type falls down if
an instance of the package is declared using any type where the number of
digits is greater than half the maximum.

Hope this helps,
-- 
David Arno



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

* Re: Higher precision and generics
  1995-03-14 16:13 ` David Arno
@ 1995-03-15 12:12   ` Duncan Sands
  1995-03-17  8:36     ` Dan Kurfis
  0 siblings, 1 reply; 12+ messages in thread
From: Duncan Sands @ 1995-03-15 12:12 UTC (permalink / raw)


|>:I am writing a package of matrix routines (in Ada!) in which some intermediate
|>: results
|>:should be calculated in higher precision than normal.  The type for normal
|>: precision is
|>:called Real and is a generic parameter of my package:
|>:generic
|>:   type Real is digits <>;
|>:package Matrix_Stuff is
|>:   ...
|>:end;
|>:
|>:In the body I would like to be able to declare Double to be a higher precision
|>:floating point type, something like:
|>:package body Matrix_Stuff is
|>:   type Double is digits 2*Real'Digits;
|>:   ...
|>:end;
|>:
|>:Unfortunately, this does not compile: apparently formal types like Real are not
|>:considered static, so Real'Digits is not considered static, and only static
|>:expressions are allowed in a "type X is digits expression" declaration.  (If
|>:I write "type Double is digits 2*Float'Digits" then it compiles fine).
|>:
|>:What can I do to get type Double to be of higher precision than Real?
|>:Can anyone please help?  And does anyone know why formal types like Real are
|>:not considered static?
|>:
|>:Thanks a lot,
|>:
|>:Duncan Sands. 
|> 
|> Probably the best thing to do in this situation is to declare a type within
|> the package body which has the highest precision possible:
|> 
|> 	type Max_Precision_type is digits System.Max_digits;
|> 
|> and to use that internaly. Even if there were a way of overcoming the need
|> for the expression after digits to be statis, the concept of your internal
|> one always being double the precision of the parameter type falls down if
|> an instance of the package is declared using any type where the number of
|> digits is greater than half the maximum.
|> 
|> Hope this helps,
|> -- 
|> David Arno

Yes, and as Keith Thompson (The_Other_Keith: kst@thomsoft.com) pointed
out to me, most Ada compilers only support either 32 or 64 bit
floating point numbers, so doubling the number of digits would always
require at least the maximum machine precision anyway.
Dan Kurfis (dkurfis@enet.net) suggested taking the higher precision type
as an additional generic parameter, which would increase the portability
and flexibility of the package.

Many thanks to you all for your help,

Duncan Sands.



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

* Re: Higher precision and generics
  1995-03-11 17:41 Higher precision and generics Duncan Sands
  1995-03-14 16:13 ` David Arno
@ 1995-03-15 15:36 ` Mats Weber
  1995-03-15 16:35   ` Peter Hermann
  1 sibling, 1 reply; 12+ messages in thread
From: Mats Weber @ 1995-03-15 15:36 UTC (permalink / raw)


In article <3jsnbf$ido@nef.ens.fr>, sands@clipper.ens.fr (Duncan Sands) wrote:

> I am writing a package of matrix routines (in Ada!) in which some
intermediate results
> should be calculated in higher precision than normal.  The type for
normal precision is
> called Real and is a generic parameter of my package:
> generic
>    type Real is digits <>;
> package Matrix_Stuff is
>    ...
> end;
> 
> In the body I would like to be able to declare Double to be a higher precision
> floating point type, something like:
> package body Matrix_Stuff is
>    type Double is digits 2*Real'Digits;
>    ...
> end;
> 
> Unfortunately, this does not compile: apparently formal types like Real
are not
> considered static, so Real'Digits is not considered static, and only static
> expressions are allowed in a "type X is digits expression" declaration.  (If
> I write "type Double is digits 2*Float'Digits" then it compiles fine).
> 
> What can I do to get type Double to be of higher precision than Real?
> Can anyone please help?  And does anyone know why formal types like Real
are not
> considered static?

They are not considered static because the design of Ada's generics leaves
the choice to the implementor as to how generics are implemented. Some
implement generics as templates that are expanded at each instantiation,
and others generate code when the generic itself is compiled. The latter
approach implies that attributes of generic formal parameters cannot be
static.

The work-around in your case is to pass the higher precision type as a
generic parameter, as follows:

generic
   type Real is digits <>;
   type Double_Real is digits <>;
package Matrix_Stuff is
   ...
end;

and then do the precision calculation when you instantiate:

type My_Real is digits ...;
type My_Double_Real is digits 2 * My_Real'Digits;  -- 'Digits is static here
                                                   -- unless My_Real is a 
                                                   -- generic formal.

package My_Matrix_Stuff is new Matrix_Stuff(My_Real, My_Double_Real);

In the body of the generic, you can, if you wish, make a check that the
precision of the actual type is sufficient:

package body Matrix_Stuff is

    ...

begin
   if Double_Real'Digits < 2 * Real'Digits then
       raise Insufficient_Precision;
   end if;
end Matrix_Stuff;

Hope this help...

Mats



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

* Re: Higher precision and generics
  1995-03-15 15:36 ` Mats Weber
@ 1995-03-15 16:35   ` Peter Hermann
  0 siblings, 0 replies; 12+ messages in thread
From: Peter Hermann @ 1995-03-15 16:35 UTC (permalink / raw)


Mats Weber (Mats.Weber@matrix.ch) wrote:
: In article <3jsnbf$ido@nef.ens.fr>, sands@clipper.ens.fr (Duncan Sands) wrote:

: > I am writing a package of matrix routines (in Ada!) in which some
: intermediate results
: > should be calculated in higher precision than normal.  The type for
: normal precision is
: > called Real and is a generic parameter of my package:
: > generic
: >    type Real is digits <>;
: > package Matrix_Stuff is
[snip]
: generic
:    type Real is digits <>;
:    type Double_Real is digits <>;
: package Matrix_Stuff is
:    ...
: end;

I do not favor Mats' solution.
We had the same situation about 20 years ago in a major finite element code:
people believed it to be useful to have Fortran code with mixed precision.
This turned out to become far too complex!
I would recommend to use the above (first) generic package in a 
straightforward manner, i.e. once instantiated for a single precision type,
next time for a double precision type (in Fortran-speak).
That's what generic units are for.

--
Peter Hermann  Tel:+49-711-685-3611 Fax:3758 ph@csv.ica.uni-stuttgart.de
Pfaffenwaldring 27, 70569 Stuttgart Uni Computeranwendungen
Team Ada: "C'mon people let the world begin" (Paul McCartney)



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

* Re: Higher precision and generics
  1995-03-15 12:12   ` Duncan Sands
@ 1995-03-17  8:36     ` Dan Kurfis
  1995-03-17 12:37       ` Peter Hermann
                         ` (2 more replies)
  0 siblings, 3 replies; 12+ messages in thread
From: Dan Kurfis @ 1995-03-17  8:36 UTC (permalink / raw)


In article <3k6ljm$bhp@nef.ens.fr>, sands@clipper.ens.fr says...
>
>|>:I am writing a package of matrix routines (in Ada!) in which some 
intermediate
>|>: results
>|>:should be calculated in higher precision than normal.  The type for 
normal
>|>: precision is
>|>:called Real and is a generic parameter of my package:
>|>:generic
>|>:   type Real is digits <>;
>|>:package Matrix_Stuff is
>|>:   ...
>|>:end;
>|>:
>|>:In the body I would like to be able to declare Double to be a higher 
precision
>|>:floating point type, something like:
>|>:package body Matrix_Stuff is
>|>:   type Double is digits 2*Real'Digits;
>|>:   ...
>|>:end;
>|>:
>|>:Unfortunately, this does not compile: apparently formal types like 
Real are not
>|>:considered static, so Real'Digits is not considered static, and only 
static
>|>:expressions are allowed in a "type X is digits expression" 
declaration.  (If
>|>:I write "type Double is digits 2*Float'Digits" then it compiles 
fine).
>|>:
>|>:What can I do to get type Double to be of higher precision than Real?
>|>:Can anyone please help?  And does anyone know why formal types like 
Real are
>|>:not considered static?
>|>:
>|>:Thanks a lot,
>|>:
>|>:Duncan Sands. 
>|> 
>|> Probably the best thing to do in this situation is to declare a type 
within
>|> the package body which has the highest precision possible:
>|> 
>|>      type Max_Precision_type is digits System.Max_digits;
>|> 
>|> and to use that internaly. Even if there were a way of overcoming the 
need
>|> for the expression after digits to be statis, the concept of your 
internal
>|> one always being double the precision of the parameter type falls 
down if
>|> an instance of the package is declared using any type where the 
number of
>|> digits is greater than half the maximum.
>|> 
>|> Hope this helps,
>|> -- 
>|> David Arno
>
>Yes, and as Keith Thompson (The_Other_Keith: kst@thomsoft.com) pointed
>out to me, most Ada compilers only support either 32 or 64 bit
>floating point numbers, so doubling the number of digits would always
>require at least the maximum machine precision anyway.
>Dan Kurfis (dkurfis@enet.net) suggested taking the higher precision type
>as an additional generic parameter, which would increase the portability
>and flexibility of the package.
>
>Many thanks to you all for your help,
>
>Duncan Sands.


Duncan,

	I've thought about your question a little more and have read some 
of the other replys (my other responses to you didn't get posted for some 
reason, hopefully this one will...).  

	First, both the Motorola and Intel FP Coprocessor chips handle 
32, 64, and 80 bit floats.  The compiler I use (ICC) always seems 
to choose the 80-bit format for intermediate results, although it 
usually uses the 64-bit format for the final result.

	Next, I think I can now explain what I was trying to say earlier 
about the use of the optional range clause.  A typical application for me 
might involve radar range data.  Most of the radars I work with have 
range accuracies no better than a few meters.  Therefore, I might create 
the following type:

	type Radar_Range_Meters is digits 1;


This type would be more than adequate for my needs, since 1/10 of a 
meter far exceeds the accuracy of my radar.  However, my compiler will 
still use the largest floating point types available because it has no 
idea what the MAXIMUM range is.  If I qualify the type declaration:

	type Radar_Range_Meters is digits 1 range 0.0..37000.0;

I now have a type which covers a maximum range of 20 nautical miles.  
This type can easily fit inside the 32-bit format.  Even more precise 
intermediate results (digits 2 or 3) will also fit in 32 bits.  When 
moving objects back and forth between memory and the coprocessor, I cut 
the number of memory transactions in half (the coprocessor itself may not 
realize any performance improvement, depending on its internal 
architecture).  This may not be important to non-realtime systems, unless 
a large number of floating point objects are to be resident im memory.  
Also, in order for this concept to REALLY work, the compiler may have to 
treat such quantities as if they were scaled and (if not symmetrical 
about zero) biased.  This treatment will create more overhead.  Maybe 
todays' compilers aren't mature enough to do this, I really don't know.  
Further, I have to believe that somebody out there has done tradeoff 
studies between the cost of always using (unnecessarily) large floating 
point formats versus the cost of implementing scaling and biasing.

	If you (or anybody out there) are planning to attend the Software 
Technology Conference in Salt Lake City next month, let me know.  I'll be 
there all week and would enjoy discussing issues like this one.  As I've 
said before, numerics are one of my weakest areas, so I would welcome any 
comments/discussion.

	Finally, I think it's important for all of us to remember that 
even though the current state-of-the art in compilers and target hardware 
may not support concepts such as the one just presented (or maybe they do 
and I just don't know it), that's no reason for us to limit our use of 
the language.  I wouldn't mind seeing the hardware play "catch-up" with 
us for a change.


						Dan Kurfis








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

* Re: Higher precision and generics
  1995-03-17  8:36     ` Dan Kurfis
@ 1995-03-17 12:37       ` Peter Hermann
  1995-03-19  1:23         ` Robert Dewar
  1995-03-18  1:45       ` Keith Thompson
  1995-03-20  9:05       ` dkurfis
  2 siblings, 1 reply; 12+ messages in thread
From: Peter Hermann @ 1995-03-17 12:37 UTC (permalink / raw)


the clever way of an unknown author  (sorry)

: >|>      type Max_Precision_type is digits System.Max_digits;

is quite attractive, but consider
1. "with system;" makes the program non-portable
2. max_digits could turn out to become an exotic overly expensive niche precision

my personal preference is to declare a portable type with 14 digits
which maps to an acceptable hw-mantissa.
on some machines this is (even) single precision.

--
Peter Hermann  Tel:+49-711-685-3611 Fax:3758 ph@csv.ica.uni-stuttgart.de
Pfaffenwaldring 27, 70569 Stuttgart Uni Computeranwendungen
Team Ada: "C'mon people let the world begin" (Paul McCartney)



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

* Re: Higher precision and generics
  1995-03-17  8:36     ` Dan Kurfis
  1995-03-17 12:37       ` Peter Hermann
@ 1995-03-18  1:45       ` Keith Thompson
  1995-03-20  9:05       ` dkurfis
  2 siblings, 0 replies; 12+ messages in thread
From: Keith Thompson @ 1995-03-18  1:45 UTC (permalink / raw)


In <3kbhv0$jcl@maple.enet.net> dkurfis@enet.net (Dan Kurfis) writes:
> 	Next, I think I can now explain what I was trying to say earlier 
> about the use of the optional range clause.  A typical application for me 
> might involve radar range data.  Most of the radars I work with have 
> range accuracies no better than a few meters.  Therefore, I might create 
> the following type:
> 
> 	type Radar_Range_Meters is digits 1;
> 
> 
> This type would be more than adequate for my needs, since 1/10 of a 
> meter far exceeds the accuracy of my radar.  However, my compiler will 
> still use the largest floating point types available because it has no 
> idea what the MAXIMUM range is.  If I qualify the type declaration:
> 
> 	type Radar_Range_Meters is digits 1 range 0.0..37000.0;
> 
> I now have a type which covers a maximum range of 20 nautical miles.  
> This type can easily fit inside the 32-bit format.

Hmm.  That's odd but legal behavior on the part of your compiler.  Both
Ada 83 and Ada 95 define a minimum implicit range for a floating-point
type definition that doesn't have an explicit range constraint (the range
is determined slightly differently in 83 vs. 95).  For your declaration

	type Radar_Range_Meters is digits 1;

this implicit range is (almost?) certain to be within the range of a
32-bit floating-point type; under Ada 95 rules, the minimum range for
this declaration is -10_000.0 .. +10_000.0.  Some implementations choose
the smallest suitable representation.  The only requirement is that the
chosen implementation has to be able to represent all the "model numbers"
defined by the declaration.

The compiler could choose either 32 or 64 bits both of your declarationss
of Radar_Range_Meters; I'm surprised it doesn't choose the same for both.

The real problem with your declaration, though, is that the digits value
specifies the *total* decimal digits of precision, not the digits after
the decimal point.  For a value of, say, 800.0, the relative error is
on the order of 100.0, not 0.1.

It happens that the smallest floating-point type on typical systems
has about 6 digits of precision, which is why your declaration happens
to work.

If you want to specify absolute precision (0.1 meters) rather than
relative precision (N digits), use fixed-point rather than floating-point.

I don't think implicit scaling or biasing makes much sense for
floating-point, given current hardware; it would simply require
extra operations for each result to maintain the representation.
For fixed-point, scaling is part of the definition (fixed-point values
are essentially scaled integers); biasing might be useful, but I don't
know of any implementations that support it.

-- 
Keith Thompson (The_Other_Keith)  kst@thomsoft.com (kst@alsys.com still works)
TeleSoft^H^H^H^H^H^H^H^H Alsys^H^H^H^H^H Thomson Software Products
10251 Vista Sorrento Parkway, Suite 300, San Diego, CA, USA, 92121-2718
That's Keith Thompson *with* a 'p', Thomson Software Products *without* a 'p'.



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

* Re: Higher precision and generics
  1995-03-17 12:37       ` Peter Hermann
@ 1995-03-19  1:23         ` Robert Dewar
  1995-03-20 16:33           ` Peter Hermann
  0 siblings, 1 reply; 12+ messages in thread
From: Robert Dewar @ 1995-03-19  1:23 UTC (permalink / raw)


Peter Hermann says:

"1. "with system;" makes the program non-portable"

This is *quite* wrong. Sure the definitions in System are target
dependent, but in many cases they are there PRECISELY to allow you
to write portable target-independent code that uses target dependent
features.

There are many situations in which the ONLY way to make a program portable
is to use the values in System. For example, a program that assumes
the addressabloe unit is 8-bits is much less portable than a program
that uses System
.Storage_Unit for this purpose.




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

* Re: Higher precision and generics
  1995-03-17  8:36     ` Dan Kurfis
  1995-03-17 12:37       ` Peter Hermann
  1995-03-18  1:45       ` Keith Thompson
@ 1995-03-20  9:05       ` dkurfis
  2 siblings, 0 replies; 12+ messages in thread
From: dkurfis @ 1995-03-20  9:05 UTC (permalink / raw)



To anyone confused by my previous post:

	Earlier today, Keith Thompson pointed out that my interpretation of 
the "digits" part of a floating-point type definition was incorrect.  Keith 
is absolutely right.  My interpretation has always been "digits to the right 
of the decimal point".  The correct interpretation renders much of my 
previous post meaningless.

	I've been stewing over this today, wondering how I could have made 
such a gross error all these years.  Since I'm still using Ada83, I still 
use MIL-STD-1815A as my primary reference.  Paragraph 3.5.7, part 6, states 
that the static expression for digits "...is the minimum number of decimal 
digits required after the point in the decimal mantissa...".  What I 
(obviously) failed to notice when I learned the language several years ago 
is that the previous paragraph had defined "mantissa" to be normalized.  
When I saw this today, I realized where my error came from.

	Anyway, I hope this didn't cause anyone too much confusion, and I 
want to thank Keith Thompson for pointing out my error.  This is exactly 
what I expect this forum to be all about, even if I'm the one being 
corrected.  Thanks.


						Dan Kurfis



	




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

* Re: Higher precision and generics
  1995-03-19  1:23         ` Robert Dewar
@ 1995-03-20 16:33           ` Peter Hermann
  1995-03-21 21:14             ` Robert Dewar
  0 siblings, 1 reply; 12+ messages in thread
From: Peter Hermann @ 1995-03-20 16:33 UTC (permalink / raw)


Robert Dewar (dewar@cs.nyu.edu) wrote:
: Peter Hermann says:

: "1. "with system;" makes the program non-portable"

: This is *quite* wrong. Sure the definitions in System are target
: dependent, but in many cases they are there PRECISELY to allow you
: to write portable target-independent code that uses target dependent
: features.

: There are many situations in which the ONLY way to make a program portable
: is to use the values in System. For example, a program that assumes
: the addressabloe unit is 8-bits is much less portable than a program
: that uses System
: .Storage_Unit for this purpose.

This is more precise, of course.
I should have written "... makes the program potentially non-portable"
My compiler issues a "non-portable construct"-warning, which 
I basically appreciate, because this is *quite*  :-)  reasonable.

--
Peter Hermann  Tel:+49-711-685-3611 Fax:3758 ph@csv.ica.uni-stuttgart.de
Pfaffenwaldring 27, 70569 Stuttgart Uni Computeranwendungen
Team Ada: "C'mon people let the world begin" (Paul McCartney)



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

* Re: Higher precision and generics
  1995-03-20 16:33           ` Peter Hermann
@ 1995-03-21 21:14             ` Robert Dewar
  0 siblings, 0 replies; 12+ messages in thread
From: Robert Dewar @ 1995-03-21 21:14 UTC (permalink / raw)


I don't like the "non-portable construct" warning for a with of System, since
I think it can lead people into the mistake of thinking that avoiding with's
of System is helpful in achieveing portability, when in fact this is just
the opposite of the real situation.




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

end of thread, other threads:[~1995-03-21 21:14 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1995-03-11 17:41 Higher precision and generics Duncan Sands
1995-03-14 16:13 ` David Arno
1995-03-15 12:12   ` Duncan Sands
1995-03-17  8:36     ` Dan Kurfis
1995-03-17 12:37       ` Peter Hermann
1995-03-19  1:23         ` Robert Dewar
1995-03-20 16:33           ` Peter Hermann
1995-03-21 21:14             ` Robert Dewar
1995-03-18  1:45       ` Keith Thompson
1995-03-20  9:05       ` dkurfis
1995-03-15 15:36 ` Mats Weber
1995-03-15 16:35   ` Peter Hermann

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