From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Thread: a07f3367d7,d2a3144038a5a80e X-Google-Attributes: gida07f3367d7,public,usenet X-Google-NewGroupId: yes X-Google-Language: ENGLISH,ASCII-7-bit Path: g2news2.google.com!news2.google.com!npeer01.iad.highwinds-media.com!news.highwinds-media.com!feed-me.highwinds-media.com!cyclone1.gnilink.net!gnilink.net!wns14feed!worldnet.att.net!attbi_s21.POSTED!53ab2750!not-for-mail From: "Jeffrey R. Carter" User-Agent: Thunderbird 2.0.0.21 (Windows/20090302) MIME-Version: 1.0 Newsgroups: comp.lang.ada Subject: Re: Question on types conversions - operations References: <4a33cb0b$0$2848$ba620e4c@news.skynet.be> In-Reply-To: <4a33cb0b$0$2848$ba620e4c@news.skynet.be> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Message-ID: NNTP-Posting-Host: 173.16.158.68 X-Complaints-To: abuse@mchsi.com X-Trace: attbi_s21 1244922966 173.16.158.68 (Sat, 13 Jun 2009 19:56:06 GMT) NNTP-Posting-Date: Sat, 13 Jun 2009 19:56:06 GMT Organization: AT&T ASP.att.net Date: Sat, 13 Jun 2009 19:56:06 GMT Xref: g2news2.google.com comp.lang.ada:6462 Date: 2009-06-13T19:56:06+00:00 List-Id: Olivier Scalbert wrote: > > I have the following three types: > type Length is new Float; > type Time is new Float; > type Speed is new Float; > > Suppose I need to compute a speed given a length and a time. > > L: Length := 100.0; > T: Time := 10.0; > S: Speed; > > How to do that ? > > With S := Speed(Float(L) / Float(T)) ? Mmmm ... not nice. > > With S := Speed(L / Length(T)), I am also not satisfy as I convert a > time in Length ... > > I am sure you have better ideas ! If you want to do unit checking, you need a new abstraction: type Scalar_Value is digits ...; type Dimensioned_Value (Length : Integer; Mass : Integer; Time : Integer) is private; function To_Scalar (Value : in Dimensioned_Value) return Scalar_Value; function To_Dimensioned (Length : in Integer; Mass : in Integer; Time : in Integer; Value : in Scalar_Value) return Dimensioned_Value; Dimension_Mismatch : exception; function "+" (Left : in Dimensioned_Value; Right : in Dimensioned_Value) return Dimensioned_Value; -- "-", "*", "/", ... subtype Length_Value is Dimensioned_Value (Length => 1, Mass => 0, Time => 0); subtype Time_Value is Dimensioned_Value (Length => 0, Mass => 0, Time => 1); subtype Speed_Value is Dimensioned_Value (Length => 1, Mass => 0, Time => -1); subtype Area_Value is Dimensioned_Value (Length => 2, Mass => 0, Time => 0); ... L: Length_Value := To_Dimensioned (1, 0, 0, 100.0); T: Time_Value := To_Dimensioned (0, 0, 1, 10.0); S: Speed_Value; S := L / T; -- OK. L := L * L; -- Raises Constraint_Error: dimensions of L * L differ from L. L := S + T; -- Raises Dimension_Mismatch. Such an abstraction can be very useful if you have to do a lot of unit checking. It can also be noticeably slower than just using floating-point types. An intermediate course is to derive a bunch of floating-point types from a common ancestor (as you have with Float), and define the appropriate operations to mix them, as others have suggested. The number of operations gets large very quickly. You can write a program to generate a package with the types and their operations; I have such a program, called Make_Units, if you'd like to see one (others do, too). One small problem when doing this is that the operations that have been "eliminated" by being declared abstract are still considered for overload resolution. A low-level approach that still retains some unit checking is to derive a bunch of types from a common ancestor, then convert to that ancestor to perform operations that mix the types. This is something you've already said you don't like [S := Speed (Float (L) / Float (T) );]. The easiest thing from the point of writing the code is to use a single type and trust to inspection and testing to get the units right. Which is best for you depends on your application. -- Jeff Carter "Beyond 100,000 lines of code you should probably be coding in Ada." P. J. Plauger 26