From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.5-pre1 (2020-06-20) on ip-172-31-74-118.ec2.internal X-Spam-Level: X-Spam-Status: No, score=-1.9 required=3.0 tests=BAYES_00,MSGID_SHORT autolearn=no autolearn_force=no version=3.4.5-pre1 Date: 22 Nov 91 21:10:01 GMT From: dove!bruce.nist.gov@uunet.uu.net (Jonathan Parker) Subject: Re: Red-faced professor gets bitten in search for portability Message-ID: <1042@dove.nist.gov> List-Id: In article <1991Nov22.090650.28@v7.vitro.com> vaxs09@v7.vitro.com writes: > In article <11919@spim.mips.COM>, murphy@mips.com (Mike Murphy) writes: > > Why not just > > check whether you indeed rounded down after doing the integer conversion? > > For example: > > FUNCTION Trunc (X: Float) RETURN Integer IS > > itrunc : integer = integer(x - 0.5); > > BEGIN > > if x - float(itrunc) >= 1.0 then > > -- rounded down, so add back a 1 > > return itrunc+1; > > else > > return itrunc; > > end if; > > END Trunc; > > > I think this version focuses more clearly on the original problem. > > FUNCTION Trunc ( X : Float ) RETURN Integer IS > i : integer := integer ( x ); > if x < float(i) then > return i - 1; > else > return i; > endif; > END Trunc; There's still more to it, if I understand the Pascal Trunc function correctly. Trunc doesn't round, it truncates. For example, Trunc(-3.999) is -3, not -4. Below is an excerpt from W. A. Whitaker's implementation of the elementary math functions in Cody and Waite's famous book on the subject. I took this unmodified from files in the Ada repository on SIMTEL-20. Floating is a generic Float type. -- Jonathan function Truncate (X : Floating) return Floating is -- Optimum code depends on how the system rounds at exact halves Z : Floating := Floating (Integer (X)); begin if X = Z then return Z; else if X > Zero then -- For instance, you can get into trouble when 1.0E-20 is overwhelmed -- by HALF and X - HALF is -HALF and that is "truncated" to -1 -- so a simple floating (Integer (X - Half)) does not work in all cases if X < Z then return Z - One; else return Z; end if; elsif X = Zero then return Zero; else if X < Z then return Z; else return Z + One; end if; end if; end if; end Truncate;