comp.lang.ada
 help / color / mirror / Atom feed
From: "Robert I. Eachus" <rieachus@attbi.com>
Subject: Re: how to round integers (Figured it out!)
Date: Tue, 17 Jun 2003 04:44:17 GMT
Date: 2003-06-17T04:44:17+00:00	[thread overview]
Message-ID: <3EEE9C81.7030904@attbi.com> (raw)
In-Reply-To: vergibdfn1hr44@corp.supernews.com

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�" <beau@hiwaay.net> 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;




  reply	other threads:[~2003-06-17  4:44 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-06-16  2:55 how to round integers Cephus�
2003-06-16  4:03 ` Charles LaCour
2003-06-16 12:12   ` Cephus�
2003-06-16 21:59   ` Jeffrey Creem
2003-06-16 10:09 ` Martin Dowie
2003-06-16 10:49 ` David C. Hoos
2003-06-16 12:18 ` how to round integers (Figured it out!) Cephus�
2003-06-16 12:34   ` David C. Hoos
2003-06-16 12:36     ` Cephus�
2003-06-16 13:12       ` David C. Hoos
2003-06-17  4:44         ` Robert I. Eachus [this message]
2003-06-17 19:20           ` Jeffrey Carter
2003-06-18  9:32             ` Robert I. Eachus
2003-06-18 18:07               ` Jeffrey Carter
2003-06-19  0:34                 ` Robert I. Eachus
2003-06-19 23:40                   ` Jeffrey Carter
replies disabled

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