comp.lang.ada
 help / color / mirror / Atom feed
From: sdd.hp.com!mips!murphy@hplabs.hpl.hp.com  (Mike Murphy)
Subject: Re: Red-faced professor gets bitten in search for portability
Date: 15 Nov 91 20:58:35 GMT	[thread overview]
Message-ID: <11919@spim.mips.COM> (raw)

In article <1991Nov15.185959.5002@milton.u.washington.edu> mfeldman@milton.u.wa
shington.edu (Michael Feldman) writes:
>Asked by students whether Ada has an equivalent of the Pascal "Trunc" 
>operation, which just returns the integer part of its argument, 
>I put together a function based on the old trick we used
>in the Fortran days.
>
>  FUNCTION Trunc (X: Float) RETURN Integer IS
>  BEGIN
>    RETURN Integer(X - 0.5);
>  END Trunc;
>
>Since conversion of Float to Integer is, in Ada, a rounding operation,
>this looks like a good solution, right? WRONG! The trouble is that,
>according to the LRM, the result of the conversion is implementation-
>dependent if the fractional part of the float quantity lies just 
>between the two integers (that is, = 0.5).  (LRM sect. 4.6)
>
>To see the hidden nastiness here, suppose Y has an integral value.
>If Y = 10.0 (say), then Trunc(Y) returns 10 on compilers where the 0.5 
>case rounds _up_, and returns 9 on compilers where the 0.5 case rounds 
>_down_. Oops! A simple bit of code falls right into a portability trap.
>
>The only solution seems to lie in forcing an integer division, since integer
>division indeed truncates, portably. So our new function is
>
>  FUNCTION Trunc (X: Float) RETURN Integer IS
>  BEGIN
>    RETURN Integer(2.0 * X) / 2;
>  END Trunc;
>
>which, I suppose, can be optimized efficiently, but seems like a
>kludgy way to do a simple truncation. I think this is an example of
>an operation that's much more easily done as an intrinsic than as
>a programmer-defined function.
>
>Any thoughts in net-land?

You are right about your first version not being portable, but
your second version seems a bit convulated to me.  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;

--mike
p.s. btw, some machines, e.g. MIPS, can either round down, or round up,
or round to the even number (the default setting).

             reply	other threads:[~1991-11-15 20:58 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1991-11-15 20:58 Mike Murphy [this message]
  -- strict thread matches above, loose matches on Subject: below --
1991-11-25  6:09 Red-faced professor gets bitten in search for portability csus.edu!wupost!spool.mu.edu!munnari.oz.au!metro!cluster!swift!sunaus!ass
1991-11-22 22:16 Dik T. Winter
1991-11-22 22:11 Dik T. Winter
1991-11-22 21:10 Jonathan Parker
1991-11-22 15:24 The Sunset Kid
1991-11-22 14:06 psinntp!vitro.com!v7.vitro.com!vaxs09
1991-11-22  2:29 micro-heart-of-gold.mit.edu!wupost!zaphod.mps.ohio-state.edu!uakari.prima
1991-11-20 23:59 micro-heart-of-gold.mit.edu!wupost!sdd.hp.com!uakari.primate.wisc.edu!use
1991-11-20  2:55 csus.edu!wupost!cs.utexas.edu!sun-barr!cronkite.Central.Sun.COM!newstop!s
1991-11-19 15:06 Norman H. Cohen
1991-11-16  0:01 Michael Feldman
1991-11-15 18:59 Michael Feldman
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox