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-Language: ENGLISH,ASCII X-Google-Thread: 103376,efbbbab26bad9cb X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 2003-06-16 21:44:18 PST Path: archiver1.google.com!news1.google.com!newsfeed.stanford.edu!logbridge.uoregon.edu!arclight.uoregon.edu!wn13feed!worldnet.att.net!204.127.198.203!attbi_feed3!attbi_feed4!attbi.com!sccrnsc02.POSTED!not-for-mail Message-ID: <3EEE9C81.7030904@attbi.com> From: "Robert I. Eachus" User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.0.2) Gecko/20021120 Netscape/7.01 X-Accept-Language: en-us, en MIME-Version: 1.0 Newsgroups: comp.lang.ada Subject: Re: how to round integers (Figured it out!) References: Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 8bit NNTP-Posting-Host: 24.62.164.137 X-Complaints-To: abuse@attbi.com X-Trace: sccrnsc02 1055825057 24.62.164.137 (Tue, 17 Jun 2003 04:44:17 GMT) NNTP-Posting-Date: Tue, 17 Jun 2003 04:44:17 GMT Organization: AT&T Broadband Date: Tue, 17 Jun 2003 04:44:17 GMT Xref: archiver1.google.com comp.lang.ada:39307 Date: 2003-06-17T04:44:17+00:00 List-Id: David C. Hoos wrote: > You are quite right. I was thinking of the algorithm which always > rounds up if there is any remainder -- e.g., if you need to know how > many boxes are required to ship N items, if M items will fit in a box. > > The algorithm you need (which will do the job without any comparisons > and conditional operations is > > (Dividend + Dividend + Divisor) / (Divisor + Divisor) > > "Cephus�" wrote in message > news:vereehn58o9be1@corp.supernews.com... Unless it causes Constraint_Error. ;-) If you really want to implement a divide with rounding in Ada, I'd use the algorithm above, plus an exception handler that used a more complex version that avoided overflow. Something like the version below. Incidently, notice that this package will not work correctly with modular types--and can't be instantiated with them in any case. It would also be interesting if someone tried this version, one that didn't need an exception handler, and one that had no exception handler and no temporary variables, and checked the execution speed. (Which one will win will depend on the compiler and the optimization levels, so there is no "right" answer.) with Ada.Text_IO; use Ada.Text_IO; procedure Test_Rounding is generic type Int is range <>; function Rounding(Dividend, Divisor: Int) return Int; function Rounding(Dividend, Divisor: Int) return Int is begin return (Dividend + Dividend + Divisor) / (Divisor + Divisor); exception when Constraint_Error => declare Temp: Int; begin Temp := Dividend rem Divisor; if Temp > Int'Last/2 or else Temp * 2 >= Divisor then return Dividend/Divisor + 1; -- Divisor is always less than or equal to Int'Last else return Dividend/Divisor; end if; end; end Rounding; function Round is new Rounding(Integer); begin Put_Line(" Rounding (2,3) is " & Integer'Image(Round(2,3))); Put_Line(" Rounding (7,5) is " & Integer'Image(Round(7,5))); Put_Line(" Rounding (25, 10) is " & Integer'Image(Round(25,10))); Put_Line(" Rounding (1_000_000_000, 1_500_000_000) is " & Integer'Image(Round(1_000_000_000, 1_500_000_000))); Put_Line(" Rounding (1_000_000_000, 2_000_000_000) is " & Integer'Image(Round(1_000_000_000, 2_000_000_000))); Put_Line(" Rounding (1_500_000_000, 2_000_000_000) is " & Integer'Image(Round(1_500_000_000, 2_000_000_000))); Put_Line(" Rounding (1_500_000_000, 2_000_000_001) is " & Integer'Image(Round(1_500_000_000, 2_000_000_001))); Put_Line(" Rounding (1_500_000_000, Integer'Last) is " & Integer'Image(Round(1_500_000_000, Integer'Last))); end Test_Rounding;