3

I would like to declare a speed range for a record type in Ada. The following won't work, but is there a way to make it work?

   --Speed in knots, range 0 to unlimited
   Speed : float Range 0.0 .. unlimited ;

I just want a zero positive value for this number...

theMayer
  • 15,456
  • 7
  • 58
  • 90

3 Answers3

5

You can't -- but since Speed is of type Float, its value can't exceed Float'Last anyway.

Speed : Float range 0.0 .. Float'Last;

(You'll likely want to declare an explicit type or subtype.)

Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
  • That seems sensible. Is there a question on here that deals with *why* ada likes specific subtypes for darn near everything? I'm new, used to c#, and this one is hard to wrap my head around. – theMayer Nov 22 '17 at 23:48
  • I left another question, since there doesn't seem to be a good answer as to why it's a good idea to create specific subtypes. I'm trying to learn to be good at Ada- – theMayer Nov 22 '17 at 23:56
4

Just for completeness, you can also define your own basic float types rather than use one called Float which may or may not have the range you require.

For example, Float is defined somewhere in the compiler or RTS (Runtime System) sources, probably as type Float is digits 7; alongside type Long_Float is digits 15;, giving you 7 and 15 digits precision respectively.

You can define yours likewise to satisfy the precision and range your application requires. The philosophy is, state what you need (in range and precision), and let the compiler satisfy it most efficiently. This is programming in the problem domain, stating what you want - rather than in the solution domain, binding your program to what a specific machine or compiler supports.

The compiler will either use the next highest precision native float (usually IEEE 32-bit or 64-bit floats) or complain that it can't do that

(e.g. if you declare

type Extra_Long_Float is digits 33 range 0.0 .. Long_Float'Last * Long_Float'Last;
your compiler may complain if it doesn't support 128 bit floats.

  • 1
    Float is defined in package Standard: "type Float is digits implementation-defined;", so you can't count on any specific precision. Long_Float is optional, so you should never use it. – Jeffrey R. Carter Nov 23 '17 at 11:09
2

Unlimited isn't possible. It would require unlimited memory. I'm not aware of any platform that has that. It's possible to write a package that provides rational numbers as big as the available memory can handle (see PragmARC.Rational_Numbers in the PragmAda Reusable Components for an example), but that's probably not what you're interested in. You can declare your own type with the maximal precision supported by your compiler:

type Speed_Value_Base is digits System.Max_Digits;
subtype Speed_Value is Speed_Value_Base range 0.0 .. Speed_Value_Base'Last;
Speed : Speed_Value;

which is probably what you're after.

Jeffrey R. Carter
  • 3,033
  • 9
  • 10
  • To clarify- I did not mean unlimited in the sense of infinity, I meant unlimited in the sense of the maximum value allowed by the architecture. So, in that sense, `Float'Last` satisfies that value - I did not know you could put an attribute of the type into the range of the declaration. – theMayer Nov 24 '17 at 16:56
  • For many compilers, Speed_Value'Last will be greater than Float'Last. – Jeffrey R. Carter Nov 25 '17 at 18:25
  • What would be the difference between putting a constraint on the declaration of the variable (what I did) as opposed to declaring a limited subtype? – theMayer Nov 26 '17 at 18:21
  • 2
    Technically, the constraint on the variable declaration is equivalent to declaring an anonymous subtype with that constraint, and then a variable of that subtype. If you declare 2 such variables with the same constraints, then you've declared 2 different anonymous subtypes (with the same constraints). From a usage point of view, there's no difference, except that declaring a subtype makes it easier to have multiple declarations with the same constraints. – Jeffrey R. Carter Nov 27 '17 at 11:09
  • "declare subtype when you plan to reuse" ... exactly ... now called the DRY principle. –  Dec 06 '17 at 12:50