tags:

views:

56

answers:

1

Hi, I have a modified textbook example as follows (the book is Understanding Ada---a software engineering approach by Bray and Pokrass):

PACKAGE SOLAR_SYSTEM IS

 TYPE PLANET IS (MERCURY, VENUS, MARS, JUPITER, SATURN, NEPTUNE);

 SUBTYPE TERRESTRIAL_PLANET IS PLANET RANGE MERCURY..MARS;
 SUBTYPE JOVIAN_PLANET IS PLANET RANGE JUPITER..NEPTUNE;

 TYPE MILES IS DIGITS 5 RANGE 0.0..5.0E9;
 TYPE PLANET_FACTS IS ARRAY (PLANET) OF MILES;

 DISTANCE_TO_SUN : CONSTANT PLANET_FACTS :=
  (MERCURY => 36.0E6, VENUS => 67.2E6, MARS => 141.7E6,
  JUPITER => 484.0E6, SATURN => 887.0E6, NEPTUNE => 2797.0E6);

 NUMBER_OF_MOONS: CONSTANT ARRAY (PLANET) OF NATURAL :=
  (MERCURY => 0, VENUS => 0, MARS => 2,
  JUPITER => 12, SATURN => 10, NEPTUNE => 2);

END SOLAR_SYSTEM;

Now to access some variables and their contents,

WITH Ada.Float_Text_IO;
WITH Ada.Text_IO;
WITH Ada.Integer_Text_IO;
WITH SOLAR_SYSTEM;
USE SOLAR_SYSTEM;


PROCEDURE TEST2 IS

BEGIN -- main program
  Ada.Integer_Text_IO.Put(Item => NUMBER_OF_MOONS(Saturn));
  Ada.Text_IO.New_Line;
  Ada.Float_Text_IO.Put(Item => DISTANCE_TO_SUN(Saturn));
END TEST2;

I can access NUMBER_OF_MOONS(Saturn) without any problem but I have difficulty to access DISTANCE_TO_SUN(Saturn). How to access it?

thanks a lot...

This is what I get on compilation with the statement

Ada.Float_Text_IO.Put(Item => DISTANCE_TO_SUN(Saturn));

list file:

1. WITH Ada.Float_Text_IO;
            |
    >>> warning: no entities of "FLOAT_TEXT_IO" are referenced

 2. WITH Ada.Text_IO;
 3. WITH Ada.Integer_Text_IO;
 4. WITH SOLAR_SYSTEM;
 5. USE SOLAR_SYSTEM;
 6.
 7.
 8. PROCEDURE TEST2 IS
 9.
10.    BEGIN -- main program
11.     Ada.Integer_Text_IO.Put(Item => NUMBER_OF_MOONS(Saturn));
12.     Ada.Text_IO.New_Line;
13.     Ada.Float_Text_IO.Put(Item => DISTANCE_TO_SUN(Saturn));
                         1            5
    >>> no candidate interpretations match the actuals:
    >>> missing argument for parameter "To" in call to "PUT" declared at a-tiflio.ads:81, instance at a-flteio.ads:20
    >>> missing argument for parameter "File" in call to "PUT" declared at a-tiflio.ads:63, instance at a-flteio.ads:20
    >>> possible missing instantiation of Text_IO.Float_IO
    >>> expected type "Standard.Float"
    >>> found type "MILES" defined at solar_system.ads:8
    >>>   ==> in call to "Put" at a-tiflio.ads:70, instance at a-flteio.ads:20

14.    END TEST2;

The problem is that DISTANCE_TO_SUN(Saturn) is of type MILES which is one of the floating point types. So just using Ada.Float_Text_IO.Put won't work.

+2  A: 

The problem is that you've declared a brand new type, MILES, which is "float-like", but is not the predefined float type. So when you try to Put an item of that type, i.e. DISTANCE_TO_SUN(Saturn), there's no Put procedure available for that type.

You have three primary choices:

1) Instantiate Float_Text_IO with the Miles type:

 package Miles_IO is new Ada.Text_IO.Float_IO(Solar_System.Miles);

and then use Miles_IO to output the value:

 Miles_IO.Put(DISTANCE_TO_SUN(Saturn));

2) Change the definition of miles to be a constrained subtype of Float:

SUBTYPE MILES IS FlOAT RANGE 0.0..5.0E9;

Then the original Float_Text_IO.Put will work just fine.

3) Since Miles is a floating point type, you can convert it before Putting it:

 Ada.Float_Text_IO.Put(Item => Float(DISTANCE_TO_SUN(Saturn)));
Marc C
Thanks a lot! I knew that the type MILES was causing problem :). It's wonderful to go through all your 3 solutions. They all work fine. 1 vote up.
yCalleecharan
To me, the best solution would be your first choice. Which one would you have picked?
yCalleecharan
MILES is of a float type with at least 5 significant digits. Say, I know some numbers with this precision e.g. 15269.12345 .Then I guess that defining TYPE MILES IS DIGITS 5 is enough and we don't need to define as a full float which takes more storage space. when we say DIGITS 5, then the compiler is providing at least 5 digits of precision. Am I thinking right?
yCalleecharan
15269.12345 has 10 significant digits! Most compilers only support two actual floating-point types (32 and 64 bits, Ada `Float` and `Long_Float`, C `float` and `double` respectively): and if you say `digits` <= 6 they will choose `Float` as the base, anything larger it'll be `Long_Float`. If you measure a person's height in cm, 3 significant figures would probably be enough, so `digits 3` would be the right declaration - it's problem-, not solution-related.
Simon Wright
For this particular situation, instantiating Float_IO with Miles would be the way to go. IMHO.
Marc C
I confused significant digits with decimal places. It's late here. Sorry for this. Thanks for the clarifications.
yCalleecharan
Does `'image` work on that type? I almost always use `'image` rather than creating generic Text_IO instantiations all over the place.
T.E.D.
Thanks. If I understand correctly, 'image works only with discrete type: enumeration and integers (source: Ada as a second language /cohen)
yCalleecharan