comp.lang.ada
 help / color / mirror / Atom feed
* Arithmetic with durations
@ 1997-09-08  0:00 Larry Coon
  1997-09-09  0:00 ` Simon Wright
  1997-09-10  0:00 ` Jerry van Dijk
  0 siblings, 2 replies; 5+ messages in thread
From: Larry Coon @ 1997-09-08  0:00 UTC (permalink / raw)



I'm still on the learning curve with Ada, and I
can't figure out the problem with this code, or
the meaning of the diagnostic message I get.

This program is a contrived example that I
excerpted from a larger program I'm working on.
The idea is to use a short simulation time to
simulate a series of events in real time.  In
this case, the real time is 1000 seconds, with
events occuring every 25 seconds.  The simulation
is to run in 100 seconds, so the simulation
events are to occur every 25 * (100/1000) = 2.5
seconds.  All that this example program does is
display the current real and simulation times at
each event.

The line that calculates the amount of simulation
time to wait for each event won't compile.  My
compiler (Thomson ObjectAda running in Windows 95)
produces the following diagnostic: "LRM:4.5.5(20)
The fixed-fixed multiplying operators shall not be
used in a context where the expected type for the
result is universal_fixed."  Being pretty new at
Ada, I've never encountered "universal_fixed" and
don't understand what I'm doing wrong or what I
need to do to fix it.  I'd appreciate any insight
from those of you with more experience than me.
Here's the example program:

with ada.text_io; use ada.text_io;
procedure main is
  total_real_time: constant duration := 1000.0;
  total_sim_time: constant duration := 100.0;
  real_delay_time: constant duration := 25.0;
  sim_delay_time: duration;
  elapsed_real_time: duration := 0.0;
  elapsed_sim_time: duration := 0.0;
  package duration_io is new fixed_io(duration);
  use duration_io;
begin
  -- Convert the delay from real time to simulation time
  -- by multiplying it by the ratio of total simulation
  -- time to total real time.  Here is where it gives the
  -- error.
  sim_delay_time := real_delay_time * total_sim_time / total_real_time;

  loop
    delay sim_delay_time;
    elapsed_real_time := elapsed_real_time + real_delay_time;
    elapsed_sim_time := elapsed_sim_time + sim_delay_time;
    put(elapsed_real_time);
    put(elapsed_sim_time);
    new_line;
    exit when elapsed_sim_time >= total_real_time;
  end loop;
end main;

 
Larry Coon
University of California
larry@fs2.assist.uci.edu
and lmcoom@home.com




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

* Re: Arithmetic with durations
  1997-09-08  0:00 Arithmetic with durations Larry Coon
@ 1997-09-09  0:00 ` Simon Wright
  1997-09-10  0:00 ` Jerry van Dijk
  1 sibling, 0 replies; 5+ messages in thread
From: Simon Wright @ 1997-09-09  0:00 UTC (permalink / raw)



Larry Coon <lmcoon@home.com> writes:

>   total_real_time: constant duration := 1000.0;
>   total_sim_time: constant duration := 100.0;
>   real_delay_time: constant duration := 25.0;
>   sim_delay_time: duration;
[...]
>   -- Convert the delay from real time to simulation time
>   -- by multiplying it by the ratio of total simulation
>   -- time to total real time.  Here is where it gives the
>   -- error.
>   sim_delay_time := real_delay_time * total_sim_time / total_real_time;

If you write

  sim_delay_time :=
      real_delay_time * duration (total_sim_time / total_real_time); -- A

or

  sim_delay_time :=
      real_delay_time * duration'(total_sim_time / total_real_time); -- B

you should do better (works fine here, 3.09 on Linux).

The relevant section of the LRM appears to be 4.5.5(18) et seq:
===========
(18)   Multiplication and division between any two fixed point types are
provided by the following two predefined operators:

(19)
       function "*"(Left, Right : universal_fixed) return universal_fixed
       function "/"(Left, Right : universal_fixed) return universal_fixed

                                   Legality Rules

(20) The above two fixed-fixed multiplying operators shall not be used
in a context where the expected type for the result is itself
universal_fixed -- the context has to identify some other numeric type
to which the result is to be converted, either explicitly or
implicitly.
============
The AARM says:
============
20.a Discussion: The small of universal_fixed is infinitesimal; no
loss of precision is permitted.  However, fixed-fixed division is
impractical to implement when an exact result is required, and
multiplication will sometimes result in unanticipated overflows in
such circumstances, so we require an explicit conversion to be
inserted in expressions like A * B * C if A, B, and C are each of some
fixed point type.
============

I'm far from an expert in this area, we don't deal much with numbers,
but I think that my version (A) means "evaluate a universal_fixed
result and convert it to duration" while (B) means "evaluate as a
duration".

I suspect that choosing appropriate intermediate fixed-point types is
less than straightforward?? (I remember fun with fixed-point types in
Coral 66, our compiler was almost guaranteed to return 0 unless you
really understood what was happening)
 
-- 
Simon Wright                        Work Email: simon.j.wright@gecm.com
GEC-Marconi Radar & Defence Systems            Voice: +44(0)1705-701778
Command & Information Systems Divsion            FAX: +44(0)1705-701800




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

* Re: Arithmetic with durations
  1997-09-10  0:00 ` Jerry van Dijk
@ 1997-09-10  0:00   ` Tucker Taft
  1997-09-11  0:00     ` Robert Dewar
  0 siblings, 1 reply; 5+ messages in thread
From: Tucker Taft @ 1997-09-10  0:00 UTC (permalink / raw)



Jerry van Dijk (jerry@jvdsys.nextjk.stuyts.nl) wrote:

: In article <34149060.2E21@home.com> lmcoon@home.com writes:

: >The line that calculates the amount of simulation
: >time to wait for each event won't compile.  My
: >compiler (Thomson ObjectAda running in Windows 95)
: >produces the following diagnostic: "LRM:4.5.5(20)
: >The fixed-fixed multiplying operators shall not be
: >used in a context where the expected type for the
: >result is universal_fixed."

: ...
:      Sim_Delay_Time := Real_Delay_Time * Total_Sim_Time / Total_Real_Time;

: If you looked up 4.5.5 you will have found that the rule used for
: the multiplication is given in 4.5.5 (19):

:    function "*" (Left, Right : universal_fixed) return universal_fixed.

: However, line (20) then makes the exception that this will only work
: if the destination type is something other then universal_fixed, either
: im- or explicit.

: However, as the result of the multiplication will be used for a
: division also defined in 4.5.5 (19) the resulting type _is_
: implicitly an universal_fixed, so the multiplication is illegal.

: To fix the problem, simply make the return type explicit, like:
: ...
:      Sim_Delay_Time := Duration (Real_Delay_Time * Total_Sim_Time)
:        / Total_Real_Time;

: Now, perhaps one of our resident RM guru's can answer the really
: interesting question: why this exception ?

The fixed-fixed multiplying operators are defined to return
infinite precision.  Of course, that is a bit inefficient to do
at run-time.  Hence, you are required to coerce the result to
some particular finitely precise numeric type.  Hence the
rule that you can't use the output of a fixed-fixed multiplying
operator as an input to another one, without first coercing it
to a particular, non-infinite-precision, numeric type.

: --

: -- Jerry van Dijk | Leiden, Holland
: -- Consultant     | Team Ada
: -- Ordina Finance | jdijk@acm.org

--
-Tucker Taft   stt@inmet.com   http://www.inmet.com/~stt/
Intermetrics, Inc.  Burlington, MA  USA




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

* Re: Arithmetic with durations
  1997-09-08  0:00 Arithmetic with durations Larry Coon
  1997-09-09  0:00 ` Simon Wright
@ 1997-09-10  0:00 ` Jerry van Dijk
  1997-09-10  0:00   ` Tucker Taft
  1 sibling, 1 reply; 5+ messages in thread
From: Jerry van Dijk @ 1997-09-10  0:00 UTC (permalink / raw)



In article <34149060.2E21@home.com> lmcoon@home.com writes:

>The line that calculates the amount of simulation
>time to wait for each event won't compile.  My
>compiler (Thomson ObjectAda running in Windows 95)
>produces the following diagnostic: "LRM:4.5.5(20)
>The fixed-fixed multiplying operators shall not be
>used in a context where the expected type for the
>result is universal_fixed."

Removing the fat, the problem becomes:

   procedure Main is

      Sim_Delay_Time : Duration;

      Real_Delay_Time: constant Duration :=   25.0;
      Total_Sim_Time : constant Duration :=  100.0;
      Total_Real_Time: constant Duration := 1000.0;

   begin
     Sim_Delay_Time := Real_Delay_Time * Total_Sim_Time / Total_Real_Time;
   end Main;

If you looked up 4.5.5 you will have found that the rule used for
the multiplication is given in 4.5.5 (19):

   function "*" (Left, Right : universal_fixed) return universal_fixed.

However, line (20) then makes the exception that this will only work
if the destination type is something other then universal_fixed, either
im- or explicit.

However, as the result of the multiplication will be used for a
division also defined in 4.5.5 (19) the resulting type _is_
implicitly an universal_fixed, so the multiplication is illegal.

To fix the problem, simply make the return type explicit, like:

   procedure Main is

      Sim_Delay_Time : Duration;

      Real_Delay_Time: constant Duration :=   25.0;
      Total_Sim_Time : constant Duration :=  100.0;
      Total_Real_Time: constant Duration := 1000.0;

   begin
     Sim_Delay_Time := Duration (Real_Delay_Time * Total_Sim_Time)
       / Total_Real_Time;
   end Main;

Now, perhaps one of our resident RM guru's can answer the really
interesting question: why this exception ?

--

-- Jerry van Dijk | Leiden, Holland
-- Consultant     | Team Ada
-- Ordina Finance | jdijk@acm.org




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

* Re: Arithmetic with durations
  1997-09-10  0:00   ` Tucker Taft
@ 1997-09-11  0:00     ` Robert Dewar
  0 siblings, 0 replies; 5+ messages in thread
From: Robert Dewar @ 1997-09-11  0:00 UTC (permalink / raw)



: In article <34149060.2E21@home.com> lmcoon@home.com writes:

: >The line that calculates the amount of simulation
: >time to wait for each event won't compile.  My
: >compiler (Thomson ObjectAda running in Windows 95)
: >produces the following diagnostic: "LRM:4.5.5(20)
: >The fixed-fixed multiplying operators shall not be
: >used in a context where the expected type for the
: >result is universal_fixed."


This is a nice example of why RM references are not as helpful as
people think they might be. Here is the GNAT diagnostic for this
particular case:

     1. procedure z is
     2.   type m is delta 0.1 range 0.0 .. 1.0;
     3.   a,b,c,d : m;
     4.
     5. begin
     6.    a := b * c * d;
                  |
        >>> type cannot be determined from context
        >>> explicit conversion to result type required

     7. end;

which I think has a much better chance of prompting someone to figure
out the solution on their own!





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

end of thread, other threads:[~1997-09-11  0:00 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1997-09-08  0:00 Arithmetic with durations Larry Coon
1997-09-09  0:00 ` Simon Wright
1997-09-10  0:00 ` Jerry van Dijk
1997-09-10  0:00   ` Tucker Taft
1997-09-11  0:00     ` Robert Dewar

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