* Re: 32 bit integer multiply routine
[not found] <38025D76.37AD9D5A@collins.rockwellDOTcom>
1999-10-12 0:00 ` 32 bit integer multiply routine Florian Weimer
@ 1999-10-12 0:00 ` Lutz Donnerhacke
1999-10-18 0:00 ` Robert Dewar
2 siblings, 0 replies; 3+ messages in thread
From: Lutz Donnerhacke @ 1999-10-12 0:00 UTC (permalink / raw)
* jeanne wrote:
>integer type, I need a way to deal with the overflow. If there is any
>canned routines or algorithms available I would appreciate you pointing
>me to the right place. Thanks in advance for your help.
Donald E. Knuth: The Art of Computer Programming, Part II, Chapter 4.
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: 32 bit integer multiply routine
[not found] <38025D76.37AD9D5A@collins.rockwellDOTcom>
@ 1999-10-12 0:00 ` Florian Weimer
1999-10-12 0:00 ` Lutz Donnerhacke
1999-10-18 0:00 ` Robert Dewar
2 siblings, 0 replies; 3+ messages in thread
From: Florian Weimer @ 1999-10-12 0:00 UTC (permalink / raw)
jeanne <jledward@collins.rockwellDOTcom> writes:
> I am trying to write a low level 32 bit integer multiply routine. I
> would entertain any suggestions. Because 32 bits is the largest system
> integer type, I need a way to deal with the overflow.
Have you tried Babylonian multiplication?
with Ada.Text_IO;
procedure Mult is
generic
Width : Positive;
package Ints is
Overflow : exception;
type Bit is new Natural range 0 .. 1;
type Bit_Index is new Natural range 0 .. Width - 1;
type Int is array (Bit_Index) of Bit;
-- LSB is at 0.
Zero : constant Int := (others => 0);
One : constant Int := (0 => 1, others => 0);
function "+" (Left, Right : Int) return Int;
function "*" (Left, Right : Int) return Int;
function To_Natural (X : Int) return Natural;
function To_Int (X : Natural) return Int;
end;
package body Ints is
function "+" (Left, Right : Int) return Int is
type Bit_And_Carry is record
B, C : Bit;
-- Result bit and new carry.
end record;
Bit_Adder : array (Bit, Bit, Bit) of Bit_And_Carry
:= (0 => (0 => (0 => (0,0),
1 => (1,0)),
1 => (0 => (1,0),
1 => (0,1))),
1 => (0 => (0 => (1,0),
1 => (0,1)),
1 => (0 => (0,1),
1 => (1,1))));
Carry : Bit := 0;
X : Int;
begin
for Pos in Bit_Index loop
declare
Result : Bit_And_Carry
:= Bit_Adder (Carry, Left (Pos), Right (Pos));
begin
X (Pos) := Result.B;
Carry := Result.C;
end;
end loop;
if Carry /= 0 then
raise Overflow;
else
return X;
end if;
end "+";
procedure Double (X : in out Int) is
begin
X := X + X;
end Double;
function "*" (Left, Right : Int) return Int is
Pos_Value : Int := Left;
-- Multiple of Left coressponding to the current bit position in
-- Left.
X : Int := Zero;
-- Temporary result.
MSB_Set : Boolean := False;
-- Most significant bit in Pos_Value is set, no more set
-- bits in Right allowed.
begin
for Pos in Bit_Index loop
if Right (Pos) /= 0 then
if MSB_Set then
raise Overflow;
end if;
X := X + Pos_Value;
end if;
if Pos_Value (Bit_Index'Last) = 1 then
MSB_Set := True;
else
Double (Pos_Value);
end if;
end loop;
return X;
end "*";
function To_Natural (X : Int) return Natural is
Position_Value : Natural := 1;
Result : Natural := 0;
begin
for Pos in Bit_Index loop
if X (Pos) /= 0 then
Result := Result + Position_Value;
end if;
if Pos /= Bit_Index'Last then
Position_Value := Position_Value * 2;
end if;
end loop;
return Result;
end To_Natural;
function To_Int (X : Natural) return Int is
Y : Natural := X;
Position_Value : Int := One;
Result : Int := Zero;
begin
for Pos in Bit_Index loop
if Y mod 2 /= 0 then
Result := Result + Position_Value;
end if;
if Pos /= Bit_Index'Last then
Double (Position_Value);
Y := Y / 2;
end if;
end loop;
return Result;
end To_Int;
end Ints;
package I is new Ints (8);
use I;
begin
Ada.Text_IO.Put_Line (Natural'Image
(To_Natural (To_Int (0) * To_Int (0))));
Ada.Text_IO.Put_Line (Natural'Image
(To_Natural (To_Int (0) * To_Int (1))));
Ada.Text_IO.Put_Line (Natural'Image
(To_Natural (To_Int (1) * To_Int (0))));
Ada.Text_IO.Put_Line (Natural'Image
(To_Natural (To_Int (1) * To_Int (1))));
Ada.Text_IO.Put_Line (Natural'Image
(To_Natural (To_Int (21) * To_Int (11))));
Ada.Text_IO.Put_Line (Natural'Image
(To_Natural (To_Int (51) * To_Int (5))));
Ada.Text_IO.Put_Line (Natural'Image
(To_Natural (To_Int (21) * To_Int (13))));
end Mult;
(Note that this is neither fully tested nor very efficient, but you'll
get the idea. Extending it to 32 bits is trivial except for the
To_Natural and To_Int functions.)
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: 32 bit integer multiply routine
[not found] <38025D76.37AD9D5A@collins.rockwellDOTcom>
1999-10-12 0:00 ` 32 bit integer multiply routine Florian Weimer
1999-10-12 0:00 ` Lutz Donnerhacke
@ 1999-10-18 0:00 ` Robert Dewar
2 siblings, 0 replies; 3+ messages in thread
From: Robert Dewar @ 1999-10-18 0:00 UTC (permalink / raw)
In article <38025D76.37AD9D5A@collins.rockwellDOTcom>,
jeanne <jledward@collins.rockwellDOTcom> wrote:
> I am trying to write a low level 32 bit integer multiply
routine. I
> would entertain any suggestions. Because 32 bits is the
largest system
> integer type, I need a way to deal with the overflow. If
there is any
> canned routines or algorithms available I would appreciate you
pointing
> me to the right place. Thanks in advance for your help.
>
> Jeanne
Just look at the s-arit64.ads/adb package in GNAT used for
64-bit multiplication with overflow detection, This should
be trivial to adapt for your purpose (the adaptation will
be covered by the GMGPL, but that should not cause you any
difficulties in usage).
Sent via Deja.com http://www.deja.com/
Before you buy.
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~1999-10-18 0:00 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
[not found] <38025D76.37AD9D5A@collins.rockwellDOTcom>
1999-10-12 0:00 ` 32 bit integer multiply routine Florian Weimer
1999-10-12 0:00 ` Lutz Donnerhacke
1999-10-18 0:00 ` Robert Dewar
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox