Path: utzoo!mnetor!uunet!husc6!bloom-beacon!mit-eddie!ll-xn!ames!pasteur!ucbvax!unizh.UUCP!nagler%olsen From: nagler%olsen@unizh.UUCP (Robert Nagler) Newsgroups: comp.lang.modula2 Subject: Re: MathLib0 procedures Message-ID: <8805100802.AA23848@klaus.olsen.uucp> Date: 10 May 88 08:02:32 GMT Sender: daemon@ucbvax.BERKELEY.EDU Reply-To: Info-Modula2 Distribution ListOrganization: The Internet Lines: 54 Modula-2 doesn't allow conversion of reals to integers, i.e. you can't convert a negative integer to a real or vice-versa. Apparently, Dr. Wirth found this to be a needed feature, so he included it in a library. Doing type coercions to CARDINAL while yield incorrect results (unless there are other bugs in the language implementation). Enclosed (below) you will find implementations of these two routines which are a "best guess" at how these procedures might be implemented in a portable library. Most compiler companies supply libraries which play around with assembly language or floating point chips, therefore it is often fruitless to look at them for algorithms. NOTE: Modula-2 has problems with twos complement integers (MININT), therefore the implementations provided will fail if they are passed MININT. One can handle the problem, but I felt it would detract from the presentation of the algorithm if I included the special case code. Rob PS. If you are wondering about the FLOAT usage (i.e. FLOAT is passed an integer), Modula-2 states that cardinals and integers are assignment compatible which means you can pass positive INTEGERs to procedures that accept CARDINALs. --------------------------------------------------------- PROCEDURE real( (* Convert an integer to a real *) x : INTEGER (* should be in the range: [ -MAX( x ) .. MAX( x ) ] *) ) : REAL; VAR result : REAL; BEGIN (* real *) IF x >= 0 THEN RETURN FLOAT( x ); END; result := FLOAT( -x ); (* breaks here if MININT (except on Univacs) *) RETURN -result; END real; PROCEDURE entier( (* Truncate a real towards negative infinity *) x : REAL (* same restrictions as "real" *) ) : INTEGER; VAR result : INTEGER; BEGIN (* entier *) IF x > 0.0 THEN RETURN TRUNC( x ); END; x := -x; result := TRUNC( x ); (* If the number is not exact, must adjust towards negative infinity *) IF FLOAT( result ) # x THEN INC( result ); END; RETURN -result; END entier;