comp.lang.ada
 help / color / mirror / Atom feed
From: Ludovic Brenta <ludovic@ludovic-brenta.org>
Subject: Re: Bit operations in Ada
Date: Sat, 24 May 2008 00:08:11 +0200
Date: 2008-05-24T00:08:11+02:00	[thread overview]
Message-ID: <87wslksmgk.fsf@ludovic-brenta.org> (raw)
In-Reply-To: g17cct$cup$1@aioe.org

Dennis Hoppe <dennis.hoppe@hoppinet.de> writes:
> Hello,
>
> I'm new to Ada and bitwise operations is a new challenge in this
> realm. My objective is to manipulate some bit strings in Ada,
> especially:
>
> a) addition/subtraction mod 2**n,
> b) change bits directly (e.g, via array access)
> c) shift operations
> d) rotate operations
> e) and, xor, not, or
>
> I started with an array of booleans of size 2**n, that provides neat
> access to individual bits by means of an index. Unfortunately,
> addition/subtraction mod 2**n is not supported, but essential for me.
>
> Next, I tried modular types (mod 2**n), but ended up with not having
> direct access to individual bits. My last attempt was to use
> Interfaces.Unsinged_n. It is a solid package that simplifies the usage
> of bitwise operations for me by adding shift and rotate
> operations. Addition modulo n works well, but I have to dispense with
> direct bit access, too.
>
> So, what is coming next? Should I go with Interfaces.Unsinged_n and
> provide a suitable function that converts the used type into an array
> of boolean? Maybe, I'm ought to use directly an array of boolean and
> try to convert the array into an Unsigned_n; if required to add two
> bit-strings.

IIUC, modular types such as Interfaces.Unsigned_n provide all
operations you need except for direct bit access.

Solution 1:

You can access bits using "and", "or", "not", "**" and "=" like so:

declare
  A : Interfaces.Unsigned_32 := 2#00000000000000000000000000000000#;
  use type Interfaces.Unsigned_32;
  Is_Bit_8_Set : Boolean;
begin
  A := A or 2 ** 5;  -- Set bit 5 to 1
  Is_Bit_8_Set := A and 2 ** 8 /= 0; -- read bit 8
end;

Solution 2:

If this is too difficult or error-prone, you could wrap that into
inlined subprograms like so:

type Bit_Number is range 0 .. 31;

procedure Set (Bit      : in Bit_Number;
               In_Value : in out Interfaces.Unsigned_32;
               To       : in     Boolean) is
   use type Interfaces.Unsigned_32;
begin
   if To = True then
      In_Value := In_Value or 2 ** Bit;
   else
      In_Value := In_Value and not 2 ** Bit;
   end if;
end Set;

function Is_Set (Bit      : in Bit_Number;
                 In_Value : in Interfaces.Unsigned_32) return Boolean is
   use type Interfaces.Unsigned_32;
begin
   return In_Value and 2 ** Bit /= 0;
end Is_Set;

Solution 3:

Another alternative is Unchecked_Conversion:

type Bit_Number is range 0 .. 31;
type Bit_Field is array (Bit_Number) of Boolean;
pragma Pack (Bit_Field);
function To_Bit_Field is
  new Ada.Unchecked_Conversion (Source => Interfaces.Unsigned_32,
                                Target => Bit_Field);
function To_Unsigned_32 is
  new Ada.Unchecked_Conversion (Source => Bit_Field,
                                Target => Interfaces.Unsigned_32);

procedure Set (Bit      : in Bit_Number;
               In_Value : in out Interfaces.Unsigned_32;
               To       : in     Boolean) is
   Field : Bit_Field := To_Bit_Field (In_Value);
begin
   Field (Bit) := To;
   In_Value := To_Unsigned_32 (Field);
end Set;

HTH

-- 
Ludovic Brenta.



  reply	other threads:[~2008-05-23 22:08 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-05-23 21:19 Bit operations in Ada Dennis Hoppe
2008-05-23 22:08 ` Ludovic Brenta [this message]
2008-05-24 15:36   ` Simon Wright
2008-06-02 13:27     ` Bit operations in Ada (endianness) Dennis Hoppe
2008-06-02 14:01       ` (see below)
2008-06-02 18:22         ` Jeffrey R. Carter
2008-06-02 17:38       ` Ludovic Brenta
2008-05-23 22:38 ` Bit operations in Ada Robert A Duff
2008-05-24  0:27   ` Randy Brukardt
2008-05-24  9:40   ` Bit operations in Ada (Thank you) Dennis Hoppe
2008-05-23 23:25 ` Bit operations in Ada Jeffrey R. 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