comp.lang.ada
 help / color / mirror / Atom feed
* Re: How do you bitwise operations in Ada '83 and '95
       [not found] <1153244316.853254.291560@m79g2000cwm.googlegroups.com>
@ 2006-07-18 18:45 ` Robert A Duff
  2006-07-18 18:53 ` jimmaureenrogers
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 49+ messages in thread
From: Robert A Duff @ 2006-07-18 18:45 UTC (permalink / raw)


"Chris L" <clusardi2k@aol.com> writes:

> Also, do you have small coding examples that demonstrate this?

If you just want bitwise logical operators, then you want an array of
Boolean.  Probably with pragma Pack.  This works in Ada 83, 95, and 05.

If you want to mix bitwise logical operators with arithmetic and the
like, then you want to use modular types, which are not available in
Ada 83.

- Bob



^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: How do you bitwise operations in Ada '83 and '95
       [not found] <1153244316.853254.291560@m79g2000cwm.googlegroups.com>
  2006-07-18 18:45 ` How do you bitwise operations in Ada '83 and '95 Robert A Duff
@ 2006-07-18 18:53 ` jimmaureenrogers
  2006-07-18 19:22   ` Jeffrey R. Carter
  2006-07-18 19:21 ` Jeffrey R. Carter
  2006-07-19  3:01 ` tmoran
  3 siblings, 1 reply; 49+ messages in thread
From: jimmaureenrogers @ 2006-07-18 18:53 UTC (permalink / raw)


Chris L wrote:
> Also, do you have small coding examples that demonstrate this?

Bitwise operations in Ada 83 are accomplished through packed
arrays of boolean. In Ada 95 you can also accomplish
bit-wise operations (and, or, xor) on modular types.

The following example shows bit-wise operations using a
packed array of boolean. The small program computes prime
number using a sieve of Erastosthenese. The array flagging
found values is implemented as a packed array of boolean.

Notice that individual bits are directly addressable as array
elements in a packed array of boolean.

with Ada.Command_Line;use Ada.Command_Line;
with Ada.Text_Io;use Ada.Text_Io;
with Ada.Integer_Text_Io;use Ada.Integer_Text_Io;

procedure Nsievebits is

   function Count (M : in     Natural ) return Natural is
      type Boolean_Array is array (2 .. M) of Boolean;
      pragma Pack (Boolean_Array);
      C : Natural       := 0;
      S : Boolean_Array := (others => True);
      I : Positive;
   begin
      for K in S'range loop
         if S(K) then
            C := C + 1;
            I := K;
            loop
               I := I + K;
               exit when I > M;
               S(I) := False;
            end loop;
         end if;
      end loop;
      return C;
   end Count;

   procedure Run (N : in     Natural ) is
      M : Natural;
   begin
      M := 2 ** N * 10_000;
      Put ("Primes up to ");
      Put (Item  => M, Width => 8);
      Put (Item  => Count (M), Width => 8);
      New_Line;
   end Run;

   N : constant Natural := Natural'Value (Argument (1));
begin
   Run (N);
   Run (N - 1);
   Run (N - 2);
end Nsievebits; 
   
Jim Rogers




^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: How do you bitwise operations in Ada '83 and '95
       [not found] <1153244316.853254.291560@m79g2000cwm.googlegroups.com>
  2006-07-18 18:45 ` How do you bitwise operations in Ada '83 and '95 Robert A Duff
  2006-07-18 18:53 ` jimmaureenrogers
@ 2006-07-18 19:21 ` Jeffrey R. Carter
  2006-07-19  3:01 ` tmoran
  3 siblings, 0 replies; 49+ messages in thread
From: Jeffrey R. Carter @ 2006-07-18 19:21 UTC (permalink / raw)


In Ada 83, you use packed arrays of Boolean or call a small C or 
assembler operation. In Ada 95, in addition to this, you can use modular 
types.

function "and" (Left : Integer; Right : Integer) return Integer;
-- Returns the bitwise logical and of Left and Right.

-- Ada 83:
function "and" (Left : Integer; Right : Integer) return Integer is
    type Bit_Set is array (1 .. Integer'Size) of Boolean;
    pragma Pack (Bit_Set);

    function To_Bit is new Unchecked_Conversion
       (Source => Integer, Target => Bit_Set);
    function To_Integer is new Unchecked_Conversion
       (Source => Bit_Set, Target => Integer);

    LB : constant Bit_Set := To_Bit (Left);
    RB : constant Bit_Set := To_Bit (Right);
begin -- "and"
    return To_Integer (LB and RB);
end "and";

Note the the language does not define whether LB (LB'First) is the LSB 
or MSB of Left.

-- Ada 95:
function "and" (Left : Integer; Right : Integer) return Integer is
    type Mod_Int is mod 2 ** Integer'Size;

    function To_Mod is new Ada.Unchecked_Conversion
       (Source => Integer, Target => Mod_Int);
    funtion To_Integer is new Ada.Unchecked_Conversion
       (Source => Mod_Int, Target => Integer);

    LM : constant Mod_Int := To_Mod (Left);
    RM : constant Mod_Int := To_Mod (Right);
begin -- "and"
    return To_Integer (LM and RM);
end "and";

-- 
Jeff Carter
"I'm a lumberjack and I'm OK."
Monty Python's Flying Circus
54



^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: How do you bitwise operations in Ada '83 and '95
  2006-07-18 18:53 ` jimmaureenrogers
@ 2006-07-18 19:22   ` Jeffrey R. Carter
  2006-07-18 21:32     ` jimmaureenrogers
  0 siblings, 1 reply; 49+ messages in thread
From: Jeffrey R. Carter @ 2006-07-18 19:22 UTC (permalink / raw)


jimmaureenrogers@worldnet.att.net wrote:
> 
> The following example shows bit-wise operations using a
> packed array of boolean. The small program computes prime
> number using a sieve of Erastosthenese. The array flagging
> found values is implemented as a packed array of boolean.

No, it doesn't. It simply shows normal array operations on a packed 
array of Boolean.

-- 
Jeff Carter
"I'm a lumberjack and I'm OK."
Monty Python's Flying Circus
54



^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: How do you bitwise operations in Ada '83 and '95
  2006-07-18 19:22   ` Jeffrey R. Carter
@ 2006-07-18 21:32     ` jimmaureenrogers
  2006-07-19  0:40       ` Jeffrey R. Carter
  0 siblings, 1 reply; 49+ messages in thread
From: jimmaureenrogers @ 2006-07-18 21:32 UTC (permalink / raw)


Jeffrey R. Carter wrote:
> jimmaureenrogers@worldnet.att.net wrote:
> >
> > The following example shows bit-wise operations using a
> > packed array of boolean. The small program computes prime
> > number using a sieve of Erastosthenese. The array flagging
> > found values is implemented as a packed array of boolean.
>
> No, it doesn't. It simply shows normal array operations on a packed
> array of Boolean.

I guess that depends upon your definition of bit-wise operations.
Very few languages support direct indexing of an array of bits.
The equivalent access operations are a lot of nasty bit masking
an bit shifting operations.

The fact is, with an Ada packed array of boolean you can
achieve the same results while maintaining the high level
abstraction of an array.

Related to bit-wise operations are record representation
clauses. Ada differs from C and C++ in ability to control
the layout of compound types. Ada provides much finer
grained control, allowing one to map types to specific
bits, controlling all padding operations, and even allowing
fields to cross word boundaries.

All these features are part of control of and access to
data at the bit level. Ada's abilities in these areas are
really quite impressive.

Jim Rogers




^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: How do you bitwise operations in Ada '83 and '95
  2006-07-18 21:32     ` jimmaureenrogers
@ 2006-07-19  0:40       ` Jeffrey R. Carter
  2006-07-19  3:55         ` jimmaureenrogers
  0 siblings, 1 reply; 49+ messages in thread
From: Jeffrey R. Carter @ 2006-07-19  0:40 UTC (permalink / raw)


jimmaureenrogers@worldnet.att.net wrote:
> 
> I guess that depends upon your definition of bit-wise operations.
> Very few languages support direct indexing of an array of bits.
> The equivalent access operations are a lot of nasty bit masking
> an bit shifting operations.

Indeed. My definition is bitwise and, or, and the like. Accessing 
individual bits is not included (though masking certainly is). I guess 
we should ask for the OP's definition.

However, your example works exactly the same if the array is not packed, 
so the fact that the Boolean values are stored as individual bits is a 
side effect of your desire to save space by packing the array, not a 
need to access individual bits, so I would argue that it is not an 
example of bitwise operations, even if accessing individual bits is 
included in the definition.

-- 
Jeff Carter
"I'm a lumberjack and I'm OK."
Monty Python's Flying Circus
54



^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: How do you bitwise operations in Ada '83 and '95
       [not found] <1153244316.853254.291560@m79g2000cwm.googlegroups.com>
                   ` (2 preceding siblings ...)
  2006-07-18 19:21 ` Jeffrey R. Carter
@ 2006-07-19  3:01 ` tmoran
  3 siblings, 0 replies; 49+ messages in thread
From: tmoran @ 2006-07-19  3:01 UTC (permalink / raw)


Several people have shown handling an array of bits, whether an
"array" or a suitably wide modular type.  But perhaps you want to
deal with things stored in bit fields.  For instance, from CLAW's
Windows keyboard interface:
        type Keypress_Info_Type is record
            Repeat_Count    : Integer range 0 .. 32767;
            Scan_Code       : Integer range 0 .. 255;
            Is_Extended_Key : Boolean;
            Also_Alt        : Boolean;
            Key_Was_Down    : Boolean;
            Is_Keyup        : Boolean;
        end record;

        for Keypress_Info_Type use record
            Repeat_Count    at 0 range 0 .. 15;
            Scan_Code       at 0 range 16 .. 23;
            Is_Extended_Key at 0 range 24 .. 24;
            Also_Alt        at 0 range 29 .. 29;
            Key_Was_Down    at 0 range 30 .. 30;
            Is_Keyup        at 0 range 31 .. 31;
        end record;
        for Keypress_Info_Type'size use 32;
then you can do, eg,
        procedure Process_Keypress(Keypress : in Keypress_Info_Type) is
        begin
          if Keypress.Repeat_Count > 0 or Keypress.Is_Extended_Key then ...



^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: How do you bitwise operations in Ada '83 and '95
  2006-07-19  0:40       ` Jeffrey R. Carter
@ 2006-07-19  3:55         ` jimmaureenrogers
  2006-07-19  4:37           ` Jeffrey R. Carter
  0 siblings, 1 reply; 49+ messages in thread
From: jimmaureenrogers @ 2006-07-19  3:55 UTC (permalink / raw)


Jeffrey R. Carter wrote:
> jimmaureenrogers@worldnet.att.net wrote:
> >
> > I guess that depends upon your definition of bit-wise operations.
> > Very few languages support direct indexing of an array of bits.
> > The equivalent access operations are a lot of nasty bit masking
> > an bit shifting operations.
>
> Indeed. My definition is bitwise and, or, and the like. Accessing
> individual bits is not included (though masking certainly is). I guess
> we should ask for the OP's definition.
>
> However, your example works exactly the same if the array is not packed,
> so the fact that the Boolean values are stored as individual bits is a
> side effect of your desire to save space by packing the array, not a
> need to access individual bits, so I would argue that it is not an
> example of bitwise operations, even if accessing individual bits is
> included in the definition.

Actually it does not work exactly the same. The algorithm is
exactly the same, and the same numbers are produced, but the
packed array of bits executes faster on my machine by a factor
of 3 and uses significantly less space (by a factor of 8).

I used a packed array of boolean specifically so that I could
store my flags in individual bits. How much more motivation
could I have to use individual bits?

Your definition of bit-wise appears to me to be based upon the
desire to use a low level abstraction to access the bits. My
definition includes all abstractions that allow access to
individual bits.  When I only programmed in C, I only
thought of bit-wise access in low level abstractions. Since I
have programmed in Ada I think of bit-wise operations in
many abstraction levels.

One of the virtues of Ada is that it allows me to use the
abstraction level most appropriate for my immediate
needs when dealing directly with individual bits or
groups of bits.

Jim Rogers

"Bring me a shrub."




^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: How do you bitwise operations in Ada '83 and '95
  2006-07-19  3:55         ` jimmaureenrogers
@ 2006-07-19  4:37           ` Jeffrey R. Carter
  2006-07-19 13:05             ` jimmaureenrogers
                               ` (2 more replies)
  0 siblings, 3 replies; 49+ messages in thread
From: Jeffrey R. Carter @ 2006-07-19  4:37 UTC (permalink / raw)


jimmaureenrogers@worldnet.att.net wrote:
> 
> Actually it does not work exactly the same. The algorithm is
> exactly the same, and the same numbers are produced, but the
> packed array of bits executes faster on my machine by a factor
> of 3 and uses significantly less space (by a factor of 8).

"The algorithm is the same and the same numbers are produced" = "works 
the same". Performance may differ, but behavior is the same. Since 
performance is a function of many things in addition to the SW, only 
behavior is a meaningful comparison. No doubt there is a 
platform/OS/compiler combination such that the unpacked version would 
run faster than the packed version does on your machine.

> Your definition of bit-wise appears to me to be based upon the
> desire to use a low level abstraction to access the bits. My
> definition includes all abstractions that allow access to
> individual bits.  When I only programmed in C, I only
> thought of bit-wise access in low level abstractions. Since I
> have programmed in Ada I think of bit-wise operations in
> many abstraction levels.

"Bitwise operations" is an inherently low-level concept. At a high 
level, your abstraction is a set. If we treat that as a high-level 
abstraction, then we hide the implementation, and neither bits nor 
Booleans appear in the handling of sets in the main program. An array of 
Booleans, packed or not, is only one possible implementation of a set. 
We could rewrite your program using the ordered-set package from the 
Ada-0X data-structures library and get the same behavior. It would not 
involve any bit-level access, though.

However, you raise an important point, and that is that we should ask 
the OP what he is trying to achieve. It may be that low-level concepts 
such as bitwise operations are an inappropriate way to approach the 
problem, and instead of showing how to do low-level things, we should be 
advising on appropriate high-level abstractions.

-- 
Jeff Carter
"I'm a lumberjack and I'm OK."
Monty Python's Flying Circus
54



^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: How do you bitwise operations in Ada '83 and '95
  2006-07-19  4:37           ` Jeffrey R. Carter
@ 2006-07-19 13:05             ` jimmaureenrogers
  2006-07-19 19:43               ` Jeffrey R. Carter
  2006-07-19 14:41             ` Robert A Duff
       [not found]             ` <1153313832.389434.144930@s13g2000cwa.googlegroups.com>
  2 siblings, 1 reply; 49+ messages in thread
From: jimmaureenrogers @ 2006-07-19 13:05 UTC (permalink / raw)


Jeffrey R. Carter wrote:
> jimmaureenrogers@worldnet.att.net wrote:
> >
> > Actually it does not work exactly the same. The algorithm is
> > exactly the same, and the same numbers are produced, but the
> > packed array of bits executes faster on my machine by a factor
> > of 3 and uses significantly less space (by a factor of 8).
>
> "The algorithm is the same and the same numbers are produced" = "works
> the same". Performance may differ, but behavior is the same. Since
> performance is a function of many things in addition to the SW, only
> behavior is a meaningful comparison. No doubt there is a
> platform/OS/compiler combination such that the unpacked version would
> run faster than the packed version does on your machine.
>
> > Your definition of bit-wise appears to me to be based upon the
> > desire to use a low level abstraction to access the bits. My
> > definition includes all abstractions that allow access to
> > individual bits.  When I only programmed in C, I only
> > thought of bit-wise access in low level abstractions. Since I
> > have programmed in Ada I think of bit-wise operations in
> > many abstraction levels.
>
> "Bitwise operations" is an inherently low-level concept. At a high
> level, your abstraction is a set. If we treat that as a high-level
> abstraction, then we hide the implementation, and neither bits nor
> Booleans appear in the handling of sets in the main program. An array of
> Booleans, packed or not, is only one possible implementation of a set.
> We could rewrite your program using the ordered-set package from the
> Ada-0X data-structures library and get the same behavior. It would not
> involve any bit-level access, though.

My example was a contribution to the Computer Language Shootout.
The corresponding C code was:

/*
 * The Great Computer Language Shootout
 * http://shootout.alioth.debian.org/
 *
 * Written by Dima Dorfman, 2004
 * Compile: gcc -std=c99 -O2 -o nsieve_bits_gcc nsieve_bits.c
 */

#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>

typedef uint_fast8_t bits;
#define	NBITS	(CHAR_BIT * sizeof(bits))

static uintmax_t
nsieve(uintmax_t m)
{
	uintmax_t count, i, j;
	bits a[m / NBITS];

	memset(a, (1 << CHAR_BIT) - 1, sizeof(a));
	count = 0;
	for (i = 2; i < m; ++i)
		if (a[i / NBITS] & (1 << i % NBITS)) {
			for (j = i + i; j < m; j += i)
				a[j / NBITS] &= ~(1 << j % NBITS);
			++count;
		}
	return (count);
}

static void
test(unsigned long n)
{
	uintmax_t count, m;

	m = (1 << n) * 10000;
	count = nsieve(m);
	printf("Primes up to %8ju %8ju\n", m, count);
}

int
main(int ac, char **av)
{
	unsigned long n;
	char *cp;

	if (ac < 2) {
usage:		fprintf(stderr, "usage: nsieve N\n");
		exit(2);
	}
	n = strtoul(av[1], &cp, 10);
	if (*av[1] == '\0' || *cp != '\0' || n == ULONG_MAX)
		goto usage;
	test(n);
	if (n >= 1)
		test(n - 1);
	if (n >= 2)
		test(n - 2);
	exit(0);
}

Here you will note that the algorithm is the same as the
Ada version. The bit-wise operations in the nsieve function
are expressed in the manner you described. According to
your analysis, if the algorithm is the same and the results
are the same, the programs are the same. Logic tells me,
therefore, that accessing individual bits of
contiguous storage through an array of boolean in Ada is
a bit-wise operation just as the combination of AND, OR and
shift operations used in the C program.

Jim Rogers




^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: How do you bitwise operations in Ada '83 and '95
       [not found]             ` <1153313832.389434.144930@s13g2000cwa.googlegroups.com>
@ 2006-07-19 13:55               ` Georg Bauhaus
  2006-07-19 14:20               ` Robert A Duff
  2006-07-19 19:30               ` Jeffrey R. Carter
  2 siblings, 0 replies; 49+ messages in thread
From: Georg Bauhaus @ 2006-07-19 13:55 UTC (permalink / raw)


On Wed, 2006-07-19 at 05:57 -0700, Chris L wrote:

> Jeff, my intent was to investigate and develop a working Ada library
> corresponding to the C source code bitwise operators: "&", "|", "<<",
> ">>", etc.

This might be of interest then:
http://adaic.org/standards/95lrm/html/RM-B-2.html






^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: How do you bitwise operations in Ada '83 and '95
       [not found]             ` <1153313832.389434.144930@s13g2000cwa.googlegroups.com>
  2006-07-19 13:55               ` Georg Bauhaus
@ 2006-07-19 14:20               ` Robert A Duff
  2006-07-19 19:30               ` Jeffrey R. Carter
  2 siblings, 0 replies; 49+ messages in thread
From: Robert A Duff @ 2006-07-19 14:20 UTC (permalink / raw)


"Chris L" <clusardi2k@aol.com> writes:

> Jeffrey R. Carter wrote:
> > However, you raise an important point, and that is that we should ask
> > the OP what he is trying to achieve.
> 
> Jeff, my intent was to investigate and develop a working Ada library
> corresponding to the C source code bitwise operators: "&", "|", "<<",
> ">>", etc.

But Ada already has these things for modular types (and for
packed arrays of boolean, which is really a higher-level feature),
so why do you want to create such a library?

By the way, since we're arguing about terminology, I do not consider the
shift operators to be "bitwise".  To me, the bitwise logical operators
are the ones that operator independently on the bits of an operand (for
"not"), or corresponding pairs of bits (for "and", "or", and "xor").
In other words, the value of bit number N of the operand(s) affects ONLY
the value of bit number N of the result.

- Bob



^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: How do you bitwise operations in Ada '83 and '95
  2006-07-19  4:37           ` Jeffrey R. Carter
  2006-07-19 13:05             ` jimmaureenrogers
@ 2006-07-19 14:41             ` Robert A Duff
       [not found]             ` <1153313832.389434.144930@s13g2000cwa.googlegroups.com>
  2 siblings, 0 replies; 49+ messages in thread
From: Robert A Duff @ 2006-07-19 14:41 UTC (permalink / raw)


"Jeffrey R. Carter" <spam.not.jrcarter@acm.not.spam.org> writes:

> "The algorithm is the same and the same numbers are produced" = "works
> the same". Performance may differ, but behavior is the same.

Since we're arguing about terminology...  ;-)

I'd say the "semantics" are the same, but the "behavior" is different.
To me, "behavior" includes anything observable.  I can observe how
long a program takes to run using a stopwatch.  Of course, I'm sure
we all realize that the semantics, as defined by the RM, does not
say anything about the time this program takes (since it contains
no delay statements).  This distinction between "semantics" and
"behavior" is mentioned in AARM-1.1.2(39.c) (which I wrote sometime
around 1991).

>... Since
> performance is a function of many things in addition to the SW, only
> behavior is a meaningful comparison.

A factor of 3 difference in speed is "meaningful" in my view!

Especially since we're talking about a language intended for real-time
use.

>... No doubt there is a
> platform/OS/compiler combination such that the unpacked version would
> run faster than the packed version does on your machine.

No doubt.

- Bob



^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: How do you bitwise operations in Ada '83 and '95
       [not found]             ` <1153313832.389434.144930@s13g2000cwa.googlegroups.com>
  2006-07-19 13:55               ` Georg Bauhaus
  2006-07-19 14:20               ` Robert A Duff
@ 2006-07-19 19:30               ` Jeffrey R. Carter
  2 siblings, 0 replies; 49+ messages in thread
From: Jeffrey R. Carter @ 2006-07-19 19:30 UTC (permalink / raw)


Chris L wrote:
> 
> Jeff, my intent was to investigate and develop a working Ada library
> corresponding to the C source code bitwise operators: "&", "|", "<<",
> ">>", etc.

I trust you now understand that such a library is unnecessary.

-- 
Jeff Carter
"People called Romanes, they go the house?"
Monty Python's Life of Brian
79



^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: How do you bitwise operations in Ada '83 and '95
  2006-07-19 13:05             ` jimmaureenrogers
@ 2006-07-19 19:43               ` Jeffrey R. Carter
  0 siblings, 0 replies; 49+ messages in thread
From: Jeffrey R. Carter @ 2006-07-19 19:43 UTC (permalink / raw)


jimmaureenrogers@worldnet.att.net wrote:
> 
> Here you will note that the algorithm is the same as the
> Ada version. The bit-wise operations in the nsieve function
> are expressed in the manner you described. According to
> your analysis, if the algorithm is the same and the results
> are the same, the programs are the same. Logic tells me,
> therefore, that accessing individual bits of
> contiguous storage through an array of boolean in Ada is
> a bit-wise operation just as the combination of AND, OR and
> shift operations used in the C program.

The algorithm is the same. The levels of abstraction differ. The Ada 
abstraction of a packed array of Boolean is higher level than accessing 
individual bits in an unsigned integer but lower level than a set 
abstraction. To me, using a set abstraction (that is implemented using 
bitwise operations) is not using bitwise operations; perhaps you would 
would disagree. Similarly, a compiler probably implements indexing a 
packed array of Boolean with shift and mask operations, but using such 
an indexing operation is not a bitwise operation.

-- 
Jeff Carter
"People called Romanes, they go the house?"
Monty Python's Life of Brian
79



^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: How do you bitwise operations in Ada '83 and '95
       [not found] <9315684D-C216-4EDA-8852-0A6BD4C275B0@amado-alves.info>
@ 2006-07-19 22:30 ` Marius Amado-Alves
  2006-07-20  7:40   ` Georg Bauhaus
  2006-07-20  9:03   ` Stephen Leake
  0 siblings, 2 replies; 49+ messages in thread
From: Marius Amado-Alves @ 2006-07-19 22:30 UTC (permalink / raw)
  To: comp.lang.ada

>> Jeff, my intent was to investigate and develop a working Ada library
>> corresponding to the C source code bitwise operators: "&", "|", "<<",
>> ">>", etc.
>
> I trust you now understand that such a library is unnecessary.

Indeed. Incidentally I have just finished a small package that shows  
well how to do bitwise operations in Ada. Package Calendar_64  
represents dates in a 64-bit string divided into several parts for  
year, month, etc. The whole package, including a test program and  
documentation is available at softdevelcoop.org (in Works / Software)

Note that I don't do bit shifting. Instead I multiply or divide by a  
magnitude. I don't think bit shifting is portable.




^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: How do you bitwise operations in Ada '83 and '95
  2006-07-19 22:30 ` Marius Amado-Alves
@ 2006-07-20  7:40   ` Georg Bauhaus
  2006-07-20  9:29     ` Colin Paul Gloster
  2006-07-20  9:03   ` Stephen Leake
  1 sibling, 1 reply; 49+ messages in thread
From: Georg Bauhaus @ 2006-07-20  7:40 UTC (permalink / raw)


Marius Amado-Alves wrote:

> Note that I don't do bit shifting. Instead I multiply or divide by a 
> magnitude. I don't think bit shifting is portable.

Why should language defined Interfaces.Shift_Right,
Interfaces.Shift_Right_Arithmetic, Rotate etc. be any less
portable than language defined arithmetic, as implemented
by the same compiler?


-- Georg 



^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: How do you bitwise operations in Ada '83 and '95
  2006-07-19 22:30 ` Marius Amado-Alves
  2006-07-20  7:40   ` Georg Bauhaus
@ 2006-07-20  9:03   ` Stephen Leake
  2006-07-20  9:38     ` Marius Amado-Alves
  2006-07-20 11:31     ` Dmitry A. Kazakov
  1 sibling, 2 replies; 49+ messages in thread
From: Stephen Leake @ 2006-07-20  9:03 UTC (permalink / raw)


Marius Amado-Alves <marius@amado-alves.info> writes:

> Note that I don't do bit shifting. Instead I multiply or divide by a
> magnitude. I don't think bit shifting is portable.

See LRM B.2, Interfaces.Shift_Left, Shift_Right, Rotate_Left, Rotate_Right.

-- 
-- Stephe



^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: How do you bitwise operations in Ada '83 and '95
  2006-07-20  7:40   ` Georg Bauhaus
@ 2006-07-20  9:29     ` Colin Paul Gloster
  2006-07-20 12:31       ` Georg Bauhaus
  0 siblings, 1 reply; 49+ messages in thread
From: Colin Paul Gloster @ 2006-07-20  9:29 UTC (permalink / raw)


On Thu, 20 Jul 2006, Georg Bauhaus wrote:

"Marius Amado-Alves wrote:

> Note that I don't do bit shifting. Instead I multiply or divide by a
> magnitude. I don't think bit shifting is portable.

Why should language defined Interfaces.Shift_Right,
Interfaces.Shift_Right_Arithmetic, Rotate etc. be any less
portable than language defined arithmetic, as implemented
by the same compiler?"

Interfaces.Shift_Right etc. are unportable in Ada:
WWW.AdaIC.org/standards/05aarm/html/AA-B-2.html#I7056

No actual implementation is required to have a datatype for Annex B 
identical to a replacement of Interfaces.Unsigned_n in another 
implementation.



^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: How do you bitwise operations in Ada '83 and '95
  2006-07-20  9:03   ` Stephen Leake
@ 2006-07-20  9:38     ` Marius Amado-Alves
  2006-07-21  9:53       ` Stephen Leake
  2006-07-20 11:31     ` Dmitry A. Kazakov
  1 sibling, 1 reply; 49+ messages in thread
From: Marius Amado-Alves @ 2006-07-20  9:38 UTC (permalink / raw)
  To: comp.lang.ada

>> Note that I don't do bit shifting. Instead I multiply or divide by a
>> magnitude. I don't think bit shifting is portable.
>
> See LRM B.2, Interfaces.Shift_Left, Shift_Right, Rotate_Left,  
> Rotate_Right.

Ok, two voices by now, so it is probably portable.

But clearly the only advantage of Interfaces over core language  
arithmetic would be speed.
And I doubt the compiler does not optimize a multiplication or  
division by a constant power of 2 by representing it as a shift  
instructions if this is the speediest method anyway.



^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: How do you bitwise operations in Ada '83 and '95
  2006-07-20  9:03   ` Stephen Leake
  2006-07-20  9:38     ` Marius Amado-Alves
@ 2006-07-20 11:31     ` Dmitry A. Kazakov
  2006-07-20 13:18       ` Marius Amado-Alves
  2006-07-21  9:58       ` Stephen Leake
  1 sibling, 2 replies; 49+ messages in thread
From: Dmitry A. Kazakov @ 2006-07-20 11:31 UTC (permalink / raw)


On Thu, 20 Jul 2006 05:03:23 -0400, Stephen Leake wrote:

> Marius Amado-Alves <marius@amado-alves.info> writes:
> 
>> Note that I don't do bit shifting. Instead I multiply or divide by a
>> magnitude. I don't think bit shifting is portable.
> 
> See LRM B.2, Interfaces.Shift_Left, Shift_Right, Rotate_Left, Rotate_Right.

Hmm, it reads (Ada 95):

"{shift} {rotate} For each such modular type in Interfaces, shifting and
rotating subprograms as specified in the declaration of Interfaces above.
These subprograms are Intrinsic. They operate on a bit-by-bit basis, using
the binary representation of the value of the operands to yield a binary
representation for the result."

That looks non-portable to me.

Here is my definition of "portable":

Let T is a modular type Unsigned_n compiled on two different machines. For
any valid X of T the result of Shift_Left (X, m) yields same numerical
value on both machines.

I don't know if that was overlooked or that was an intent of language
designers to get at the underlying machine representation. Probably the
latter. I'm not a language lawyer, though.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: How do you bitwise operations in Ada '83 and '95
  2006-07-20  9:29     ` Colin Paul Gloster
@ 2006-07-20 12:31       ` Georg Bauhaus
  2006-07-20 13:08         ` Colin Paul Gloster
  0 siblings, 1 reply; 49+ messages in thread
From: Georg Bauhaus @ 2006-07-20 12:31 UTC (permalink / raw)


On Thu, 2006-07-20 at 11:29 +0200, Colin Paul Gloster wrote:


> No actual implementation is required to have a datatype for Annex B 
> identical to a replacement of Interfaces.Unsigned_n in another 
> implementation.

Well, yes, the Unsigned_n types are per implementation.
Realistically, how is

  type Time is mod 2 ** 96;

any more portable than Unsigned_96?

The definition might express in a better way that there is no
dependence on hardware.





^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: How do you bitwise operations in Ada '83 and '95
  2006-07-20 12:31       ` Georg Bauhaus
@ 2006-07-20 13:08         ` Colin Paul Gloster
  2006-07-20 13:29           ` Marius Amado-Alves
  2006-07-20 13:49           ` Georg Bauhaus
  0 siblings, 2 replies; 49+ messages in thread
From: Colin Paul Gloster @ 2006-07-20 13:08 UTC (permalink / raw)


On Thu, 20 Jul 2006, Georg Bauhaus wrote:

"On Thu, 2006-07-20 at 11:29 +0200, Colin Paul Gloster wrote:


> No actual implementation is required to have a datatype for Annex B 
> identical to a replacement of Interfaces.Unsigned_n in another 
> implementation.

Well, yes, the Unsigned_n types are per implementation.
Realistically, how is

  type Time is mod 2 ** 96;

any more portable than Unsigned_96?

The definition might express in a better way that there is no
dependence on hardware."

Being an implementation of a strongly typed language, if an implementation 
does have Interfaces.Unsigned_96 then the returned value from function 
Shift_Left  (Value : Unsigned_96; Amount : Natural) return Unsigned_96 
can not be assigned to a variable of type Time is mod 2 ** 96 without 
conversion.

As another example, suppose one did not have type Time and wanted
Interfaces.Unsigned_96 but Interfaces.Unsigned_96 did not exist in one 
particular implementation but e.g. Interfaces.Unsigned_128 did. The code 
relying on Interfaces.Unsigned_96 would not work on that implementation. 
Sure, it is easy to simply change it: but that is unportable.



^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: How do you bitwise operations in Ada '83 and '95
  2006-07-20 11:31     ` Dmitry A. Kazakov
@ 2006-07-20 13:18       ` Marius Amado-Alves
  2006-07-21  9:58       ` Stephen Leake
  1 sibling, 0 replies; 49+ messages in thread
From: Marius Amado-Alves @ 2006-07-20 13:18 UTC (permalink / raw)
  To: comp.lang.ada

> I don't know if that was overlooked or that was an intent of language
> designers to get at the underlying machine representation. Probably  
> the
> latter.

Almost certainly the latter. Which would make it non-portable by  
definition.




^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: How do you bitwise operations in Ada '83 and '95
  2006-07-20 13:08         ` Colin Paul Gloster
@ 2006-07-20 13:29           ` Marius Amado-Alves
  2006-07-20 13:49           ` Georg Bauhaus
  1 sibling, 0 replies; 49+ messages in thread
From: Marius Amado-Alves @ 2006-07-20 13:29 UTC (permalink / raw)
  To: Colin Paul Gloster; +Cc: comp.lang.ada

> Realistically, how is
>
>   type Time is mod 2 ** 96;
>
> any more portable than Unsigned_96?...

You have a point there and you (both) have answered it. In sum, mod 2  
** 96 is slightly less dependent than Unsigned_96.

In an ideal world compilers would translate mod 2 * 1_000_000 to the  
corresponding packed array of bits and save us the trouble :-)




^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: How do you bitwise operations in Ada '83 and '95
  2006-07-20 13:08         ` Colin Paul Gloster
  2006-07-20 13:29           ` Marius Amado-Alves
@ 2006-07-20 13:49           ` Georg Bauhaus
  2006-07-21  5:23             ` Colin Paul Gloster
  1 sibling, 1 reply; 49+ messages in thread
From: Georg Bauhaus @ 2006-07-20 13:49 UTC (permalink / raw)


On Thu, 2006-07-20 at 15:08 +0200, Colin Paul Gloster wrote:

>  the returned value from function 
> Shift_Left  (Value : Unsigned_96; Amount : Natural) return Unsigned_96 
> can not be assigned to a variable of type Time is mod 2 ** 96 without 
> conversion.

type Time is new Unsigned_96;

In fact,
  type Time is private;
and then the above.

> As another example, suppose one did not have type Time and wanted
> Interfaces.Unsigned_96 but Interfaces.Unsigned_96 did not exist in one 
> particular implementation but e.g. Interfaces.Unsigned_128 did. The code 
> relying on Interfaces.Unsigned_96 would not work on that implementation. 

OK, that is a good point when the program is operating on modular
numbers or bit sets.
But if an algorithm is about shifting bits really, then why
not use the subprograms that say "Shift_zzzz" in their names, and
that were made for shifting bits?
If there is room for even more than 96 bits in modular numbers,
I'd say that "easily ported" (from a 96 bit system to a 128 bit
system) is a better description than "unportable".
I guess for the "*" -> shift optimization to work in the general case,
the **2 factors will have to be statically known anyway. (They are,
in MAA's program.)






^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: How do you bitwise operations in Ada '83 and '95
       [not found] <BFF12262-F906-4F9A-B867-D0373609F038@amado-alves.info>
@ 2006-07-20 16:40 ` Marius Amado-Alves
  0 siblings, 0 replies; 49+ messages in thread
From: Marius Amado-Alves @ 2006-07-20 16:40 UTC (permalink / raw)
  To: comp.lang.ada

> Realistically, how is
>
>   type Time is mod 2 ** 96;
>
> any more portable than Unsigned_96?...

You have a point there and you (both) have answered it. In sum, mod 2  
** 96 is slightly less dependent than Unsigned_96.

In an ideal world compilers translate mod 2 ** 1_000_000 to the  
corresponding packed array of bits and save us the trouble :-)

BTW since yesterday Calendar_64 has undergone major improvements  
including bug fixes.



^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: How do you bitwise operations in Ada '83 and '95
  2006-07-20 17:54 ` tmoran
@ 2006-07-20 18:30   ` Marius Amado-Alves
  2006-07-20 19:36     ` tmoran
  0 siblings, 1 reply; 49+ messages in thread
From: Marius Amado-Alves @ 2006-07-20 18:30 UTC (permalink / raw)
  To: comp.lang.ada


>> To me bit shifting is a positional thing. Surely positions differ
>    And why is it again that you want to DIY instead of using a  
> record...

I need dates in a 64-bit string. Calendar_64 does just that.

Why I need dates in a 64-bit string? Short version of a long story:  
to store then in Mneson vertices as 64-bit integers.

Why I use a modular type instead of a record with rep. clauses? More  
practical. (And I think safer, I think rec. rep. clauses are not as  
strongly required by the RM to be met by the implementation, which is  
yes very strange, but that's the reading of the RM I have, maybe I am  
wrong.) On the practical side, I particularly like that the  
predefined binary relations for the modular Time type can be used as is.





^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: How do you bitwise operations in Ada '83 and '95
  2006-07-20 18:30   ` Marius Amado-Alves
@ 2006-07-20 19:36     ` tmoran
  2006-07-20 22:09       ` Simon Wright
  0 siblings, 1 reply; 49+ messages in thread
From: tmoran @ 2006-07-20 19:36 UTC (permalink / raw)


>Why I use a modular type instead of a record with rep. clauses? More
>practical. (And I think safer, I think rec. rep. clauses are not as
>strongly required by the RM to be met by the implementation, which is
   If you really want to be portable to a compiler meeting the absolute
minimum standard, then you are, of course, doing your own 64 bit
arithmetic, since both Integer and System.Max_Binary_Modulus are only
required to be 16 bits.
   Ada is designed to be highly readable and to aid in creating correct
programs.  Surely a record rep clause, and then simple usage of its
components, is more readable, and more likely to be correct, and even more
likely to generate optimized code, than source code littered with complex
arithmetic expressions.
   When I used languages other than Ada, I thought of a compiler as a tool
to convert my source code to binary.  With Ada, though, I think of the
compiler as an assistant, doing the scut work (like shifting and masking
in this case) and watching to tell me of any obvious errors.  It's a
different world view.



^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: How do you bitwise operations in Ada '83 and '95
       [not found] <CD6E3BB8-52D2-4EED-A790-0184FE56A99A@amado-alves.info>
@ 2006-07-20 20:41 ` Marius Amado-Alves
  2006-07-20 23:13   ` Randy Brukardt
  0 siblings, 1 reply; 49+ messages in thread
From: Marius Amado-Alves @ 2006-07-20 20:41 UTC (permalink / raw)
  To: comp.lang.ada

> Surely a record rep clause, and then simple usage of its
> components, is more readable, and more likely to be correct, and  
> even more
> likely to generate optimized code, than source code littered with  
> complex
> arithmetic expressions.

Actually, in this case, no. Time needs an order relation. Implemented  
as a record you have to write the relation functions--and you can  
botch there. Implemented as a modular type the predefined relation  
functions are gratis--and surely correct. And the expressions are not  
complex. Once you get the masks and magnitudes right, it's simply

Part := (Whole and Mask) / Magnitude.







^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: How do you bitwise operations in Ada '83 and '95
  2006-07-20 19:36     ` tmoran
@ 2006-07-20 22:09       ` Simon Wright
  2006-07-21 10:07         ` Stephen Leake
  0 siblings, 1 reply; 49+ messages in thread
From: Simon Wright @ 2006-07-20 22:09 UTC (permalink / raw)


tmoran@acm.org writes:

>    Ada is designed to be highly readable and to aid in creating
> correct programs.  Surely a record rep clause, and then simple usage
> of its components, is more readable, and more likely to be correct,
> and even more likely to generate optimized code, than source code
> littered with complex arithmetic expressions.

Unless you are concerned with endian-independence, of course, when the
rep clause becomes highly incomprehensible. I have a feeling that
shift&mask ends up more understandable and reviewable.



^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: How do you bitwise operations in Ada '83 and '95
  2006-07-20 20:41 ` Marius Amado-Alves
@ 2006-07-20 23:13   ` Randy Brukardt
  2006-07-21  5:38     ` Marius Amado-Alves
  0 siblings, 1 reply; 49+ messages in thread
From: Randy Brukardt @ 2006-07-20 23:13 UTC (permalink / raw)


"Marius Amado-Alves" <marius@amado-alves.info> wrote in message
news:mailman.42.1153428092.30988.comp.lang.ada@ada-france.org...
> > Surely a record rep clause, and then simple usage of its
> > components, is more readable, and more likely to be correct, and  even
more
> > likely to generate optimized code, than source code littered with
complex
> > arithmetic expressions.
>
> Actually, in this case, no. Time needs an order relation. Implemented
> as a record you have to write the relation functions--and you can
> botch there.

True enough.

> Implemented as a modular type the predefined relation
> functions are gratis--and surely correct.

Only if you've carefully laid out the order of the bits so that will work.
Which is much more likely to ruin the alignment of the bit-field components
(an important part of maximum performance).

> And the expressions are not
> complex. Once you get the masks and magnitudes right, it's simply
>
> Part := (Whole and Mask) / Magnitude.

But that's for each component. Surely you do other operations (like
difference in seconds) where the expressions are  far more complex?

All-in-all, I prefer the record representation. (Case in point: the
Janus/Ada Calendar.Time implementation is a 64-bit record type.) But there
may be exceptions - and, in any case, if the type is properly encapsulated,
it's not that big of a deal either way (no one should be looking at the raw
representation of times no matter what they are).

                         Randy.





^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: How do you bitwise operations in Ada '83 and '95
  2006-07-20 13:49           ` Georg Bauhaus
@ 2006-07-21  5:23             ` Colin Paul Gloster
  2006-07-21  8:00               ` Georg Bauhaus
  0 siblings, 1 reply; 49+ messages in thread
From: Colin Paul Gloster @ 2006-07-21  5:23 UTC (permalink / raw)


On Thu, 20 Jul 2006, Georg Bauhaus wrote:

"On Thu, 2006-07-20 at 15:08 +0200, Colin Paul Gloster wrote:

>  the returned value from function 
> Shift_Left  (Value : Unsigned_96; Amount : Natural) return Unsigned_96 
> can not be assigned to a variable of type Time is mod 2 ** 96 without 
> conversion.

type Time is new Unsigned_96;

In fact,
  type Time is private;
and then the above."

No, actually you need a subtype for your example but I accept your point 
is still valid. Uncomment the following comments for a compilation error.
procedure Subtype_Instead_Of_Type is
   type T1 is range 0..19;
   --type T2 is new T1;
   subtype ST is T1;
   V1 : T1;
   --V2 : T2;
   V3 : ST;
begin
   V1 := 7;
   --V2 := V1;
   V3 := V1;
end;


"[..]
But if an algorithm is about shifting bits really, then why
not use the subprograms that say "Shift_zzzz" in their names, and
that were made for shifting bits?"

If you can and all the platforms you wish to have the program on allow it, 
it could be done. Another question is, why did the Ada 95 standard and the 
Ada 2005 standard provide those functions in such a form which is less 
general than Ada's multiplication and power operators and C's shift 
operators?

" If there is room for even more than 96 bits in modular 
numbers, [..]"

Whereas if the largest Interfaces.Unsigned_n is smaller than needed...



^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: How do you bitwise operations in Ada '83 and '95
  2006-07-20 23:13   ` Randy Brukardt
@ 2006-07-21  5:38     ` Marius Amado-Alves
  2006-07-21 22:09       ` Randy Brukardt
  0 siblings, 1 reply; 49+ messages in thread
From: Marius Amado-Alves @ 2006-07-21  5:38 UTC (permalink / raw)
  To: comp.lang.ada

>> Implemented as a modular type the predefined relation
>> functions are gratis--and surely correct.
>
> Only if you've carefully laid out the order of the bits so that  
> will work.

Sure, but that's really easy, no? Year, Month, Day, Seconds...

> Which is much more likely to ruin the alignment of the bit-field  
> components
> (an important part of maximum performance).

For records. For a 64-bit unit it does not matter for the "<"  
functions where the fields are.

>> And the expressions are not
>> complex. Once you get the masks and magnitudes right, it's simply
>>
>> Part := (Whole and Mask) / Magnitude.
>
> But that's for each component. Surely you do other operations (like
> difference in seconds) where the expressions are  far more complex?

Actually, in this case, no. I leave it to Ada.Calendar. Convert,  
compute, convert. This limitation is documented.

> All-in-all, I prefer the record representation.

For Calendar_64 I specifically wanted a 64-bit string, it was a  
requirement.

If I was to implement Ada.Calendar I think I would use a record too,  
because it is a private type by definition, so I would have to write  
the "<" functions anyway.

> Janus/Ada Calendar.Time implementation is a 64-bit record type

Just curious: is it aligned properly i.e. if you uncheckedly convert  
to a 64-bit modular will the modular "<" functions work properly i.e.  
represent the relations between the dates properly?

Of course a Calendar_64 for a specific compiler/platform could take  
advantage of the respective Ada.Calendar representation.





^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: How do you bitwise operations in Ada '83 and '95
  2006-07-21  5:23             ` Colin Paul Gloster
@ 2006-07-21  8:00               ` Georg Bauhaus
  0 siblings, 0 replies; 49+ messages in thread
From: Georg Bauhaus @ 2006-07-21  8:00 UTC (permalink / raw)


Colin Paul Gloster wrote:
> On Thu, 20 Jul 2006, Georg Bauhaus wrote:


> type Time is new Unsigned_96;
> 
> In fact,
>   type Time is private;
> and then the above."
> 
> No, actually you need a subtype for your example but I accept your point 
> is still valid.

The Time type derived from Unsigned_96 will be a dedicated type with
bit fiddling operations. I won't want to assign arbitrary base type
values to Time objects?

procedure Derived_Type_Instead_Of_Subtype is
    type Time is new Unsigned_96;

    V1 : Time;
    V2 : Time;
    V3 : Unsigned_96;
 begin
    V1 := Shift_Left(7, First_Bit_Year);
    V2 := V1;
    -- V3 := V2;  -- does not compile, good
 end;

Anyway, I see a razor blade coming close to hair.


-- Georg 



^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: How do you bitwise operations in Ada '83 and '95
  2006-07-20  9:38     ` Marius Amado-Alves
@ 2006-07-21  9:53       ` Stephen Leake
  0 siblings, 0 replies; 49+ messages in thread
From: Stephen Leake @ 2006-07-21  9:53 UTC (permalink / raw)


Marius Amado-Alves <marius@amado-alves.info> writes:

>>> Note that I don't do bit shifting. Instead I multiply or divide by a
>>> magnitude. I don't think bit shifting is portable.
>>
>> See LRM B.2, Interfaces.Shift_Left, Shift_Right, Rotate_Left,
>> Rotate_Right.
>
> Ok, two voices by now, so it is probably portable.

As Colin has pointed out, Interfaces.Unsigned_n is not required on all
machines; a machine with a 36 bit word won't have
Interfaces.Unsigned_32.

So you need to be precise about what you mean by "portable". We
usually take that to mean "code works without change on a reasonable
set of CPUs and operating system", where "reasonable" means "the ones
I care about" :).

> But clearly the only advantage of Interfaces over core language
> arithmetic would be speed.

There's no reason to think one would be faster than the other. It
depends on the CPU and compiler.

-- 
-- Stephe



^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: How do you bitwise operations in Ada '83 and '95
  2006-07-20 11:31     ` Dmitry A. Kazakov
  2006-07-20 13:18       ` Marius Amado-Alves
@ 2006-07-21  9:58       ` Stephen Leake
  2006-07-21 12:09         ` Dmitry A. Kazakov
  1 sibling, 1 reply; 49+ messages in thread
From: Stephen Leake @ 2006-07-21  9:58 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:

> On Thu, 20 Jul 2006 05:03:23 -0400, Stephen Leake wrote:
>
>> Marius Amado-Alves <marius@amado-alves.info> writes:
>> 
>>> Note that I don't do bit shifting. Instead I multiply or divide by a
>>> magnitude. I don't think bit shifting is portable.
>> 
>> See LRM B.2, Interfaces.Shift_Left, Shift_Right, Rotate_Left, Rotate_Right.
>
> Hmm, it reads (Ada 95):
>
> "{shift} {rotate} For each such modular type in Interfaces, shifting and
> rotating subprograms as specified in the declaration of Interfaces above.
> These subprograms are Intrinsic. They operate on a bit-by-bit basis, using
> the binary representation of the value of the operands to yield a binary
> representation for the result."
>
> That looks non-portable to me.
>
> Here is my definition of "portable":
>
> Let T is a modular type Unsigned_n compiled on two different machines. For
> any valid X of T the result of Shift_Left (X, m) yields same numerical
> value on both machines.
>
> I don't know if that was overlooked or that was an intent of language
> designers to get at the underlying machine representation. Probably the
> latter. I'm not a language lawyer, though.

I'm missing something here. Assuming machines A and B both have
Unsigned_16, please show me an Ada statement that produces
different results on the two machines.

I can see shift/rotate is non-portable if machine B doesn't have
Unsigned_16, but otherwise I don't see the problem.

Hmm. I suppose if machine A is one's complement, and machine B is
two's compliment? No, the Unsigned bit representation is still the
same; that's why these operations are not defined on signed types.

-- 
-- Stephe



^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: How do you bitwise operations in Ada '83 and '95
  2006-07-20 22:09       ` Simon Wright
@ 2006-07-21 10:07         ` Stephen Leake
  2006-07-21 19:09           ` Simon Wright
  0 siblings, 1 reply; 49+ messages in thread
From: Stephen Leake @ 2006-07-21 10:07 UTC (permalink / raw)


Simon Wright <simon@pushface.org> writes:

> tmoran@acm.org writes:
>
>>    Ada is designed to be highly readable and to aid in creating
>> correct programs.  Surely a record rep clause, and then simple usage
>> of its components, is more readable, and more likely to be correct,
>> and even more likely to generate optimized code, than source code
>> littered with complex arithmetic expressions.
>
> Unless you are concerned with endian-independence, of course, when the
> rep clause becomes highly incomprehensible. 

Not in Ada 2005; 'Bit_Order is required to work "nicely" to make
endian-independent rep clauses. See AI95-00133 and
http://www.ada-auth.org/ai-files/grab_bag/bitorder.pdf.

However, not even GNAT implements this yet. We need to put more
pressure on the compiler vendors. Or be more patient :).

> I have a feeling that shift&mask ends up more understandable 

Never.

> and reviewable.

In Ada 95, maybe. In Ada 2005, not.

-- 
-- Stephe



^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: How do you bitwise operations in Ada '83 and '95
  2006-07-21  9:58       ` Stephen Leake
@ 2006-07-21 12:09         ` Dmitry A. Kazakov
  2006-07-21 19:03           ` Simon Wright
  0 siblings, 1 reply; 49+ messages in thread
From: Dmitry A. Kazakov @ 2006-07-21 12:09 UTC (permalink / raw)


On Fri, 21 Jul 2006 05:58:18 -0400, Stephen Leake wrote:

> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
> 
>> On Thu, 20 Jul 2006 05:03:23 -0400, Stephen Leake wrote:
>>
>>> Marius Amado-Alves <marius@amado-alves.info> writes:
>>> 
>>>> Note that I don't do bit shifting. Instead I multiply or divide by a
>>>> magnitude. I don't think bit shifting is portable.
>>> 
>>> See LRM B.2, Interfaces.Shift_Left, Shift_Right, Rotate_Left, Rotate_Right.
>>
>> Hmm, it reads (Ada 95):
>>
>> "{shift} {rotate} For each such modular type in Interfaces, shifting and
>> rotating subprograms as specified in the declaration of Interfaces above.
>> These subprograms are Intrinsic. They operate on a bit-by-bit basis, using
>> the binary representation of the value of the operands to yield a binary
>> representation for the result."
>>
>> That looks non-portable to me.
>>
>> Here is my definition of "portable":
>>
>> Let T is a modular type Unsigned_n compiled on two different machines. For
>> any valid X of T the result of Shift_Left (X, m) yields same numerical
>> value on both machines.
>>
>> I don't know if that was overlooked or that was an intent of language
>> designers to get at the underlying machine representation. Probably the
>> latter. I'm not a language lawyer, though.
> 
> I'm missing something here. Assuming machines A and B both have
> Unsigned_16, please show me an Ada statement that produces
> different results on the two machines.
> 
> I can see shift/rotate is non-portable if machine B doesn't have
> Unsigned_16, but otherwise I don't see the problem.
> 
> Hmm. I suppose if machine A is one's complement, and machine B is
> two's compliment? No, the Unsigned bit representation is still the
> same; that's why these operations are not defined on signed types.

It depends on endianness. Provided that storage elements are octets on both 
machines, which assumption could be wrong, 128 shifted left might yield  0,
256 or even 64 (what is "left"?).

When considering *any* thinkable architecture, it might be even impossible 
to implement Shift_* at all. Let some crazy hardware store numbers in only 
odd bits, reserving even ones for something else (like a check-sum). On 
such imaginary hardware Shift_Left (*, 1) wouldn't even yield a valid 
number! Actually "they operate on a bit-by-bit basis" is quite hazy. What 
is bit? Which bits are adjacent? How are they ordered? What does "left" 
mean? Which bits are of the number? etc.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: How do you bitwise operations in Ada '83 and '95
  2006-07-21 12:09         ` Dmitry A. Kazakov
@ 2006-07-21 19:03           ` Simon Wright
  2006-07-22  8:32             ` Dmitry A. Kazakov
  0 siblings, 1 reply; 49+ messages in thread
From: Simon Wright @ 2006-07-21 19:03 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:

> It depends on endianness. Provided that storage elements are octets
> on both machines, which assumption could be wrong, 128 shifted left
> might yield 0, 256 or even 64 (what is "left"?).

You might as well argue that the C operator<< could produce 64 or 256.

> When considering *any* thinkable architecture, it might be even
> impossible to implement Shift_* at all. Let some crazy hardware
> store numbers in only odd bits, reserving even ones for something
> else (like a check-sum). On such imaginary hardware Shift_Left (*,
> 1) wouldn't even yield a valid number! Actually "they operate on a
> bit-by-bit basis" is quite hazy. What is bit? Which bits are
> adjacent? How are they ordered? What does "left" mean? Which bits
> are of the number? etc.

One would think the market for hardware like that would be pretty
thin; not really a "thinkable" architecture. Certainly not
interesting.



^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: How do you bitwise operations in Ada '83 and '95
  2006-07-21 10:07         ` Stephen Leake
@ 2006-07-21 19:09           ` Simon Wright
  2006-07-21 19:45             ` tmoran
  2006-07-23 15:59             ` Stephen Leake
  0 siblings, 2 replies; 49+ messages in thread
From: Simon Wright @ 2006-07-21 19:09 UTC (permalink / raw)


Stephen Leake <stephen_leake@acm.org> writes, responding to me:

>> I have a feeling that shift&mask ends up more understandable 
>
> Never.
>
>> and reviewable.
>
> In Ada 95, maybe. In Ada 2005, not.

Really, understandable and reviewable are very similar, so I don't see
how something could be (possibly) more reviewable while never more
understandable.

Seriously, the C

  field = (longword >> 15) & 0x3f;

is pretty clear.

I didn't know about the 05 change to 'Bit_Order, sounds good, not much
help with the current project though!



^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: How do you bitwise operations in Ada '83 and '95
  2006-07-21 19:09           ` Simon Wright
@ 2006-07-21 19:45             ` tmoran
  2006-07-23 15:59             ` Stephen Leake
  1 sibling, 0 replies; 49+ messages in thread
From: tmoran @ 2006-07-21 19:45 UTC (permalink / raw)


> Seriously, the C
>
>   field = (longword >> 15) & 0x3f;
>
> is pretty clear.
Not as clear, and more error prone than
    field := soccer_schedule.location;
Not to mention that "field" could be of type "soccer_field_ids" in Ada,
thus allowing the compiler to check that you aren't assigning the hour of
the game to the variable "field", rather than of type "Unsigned_96" which
prevents the compiler from helping you guard against error.



^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: How do you bitwise operations in Ada '83 and '95
  2006-07-21  5:38     ` Marius Amado-Alves
@ 2006-07-21 22:09       ` Randy Brukardt
  0 siblings, 0 replies; 49+ messages in thread
From: Randy Brukardt @ 2006-07-21 22:09 UTC (permalink / raw)


"Marius Amado-Alves" <marius@amado-alves.info> wrote in message
news:mailman.43.1153460313.30988.comp.lang.ada@ada-france.org...
...
> > Which is much more likely to ruin the alignment of the bit-field
components
> > (an important part of maximum performance).
>
> For records. For a 64-bit unit it does not matter for the "<"
> functions where the fields are.

That is only true on a 64-bit machine. On more typical 32-bit machines, you
are doing double precision math to extract a few bits from the middle.
That's going to be more expensive.

> >> And the expressions are not
> >> complex. Once you get the masks and magnitudes right, it's simply
> >>
> >> Part := (Whole and Mask) / Magnitude.
> >
> > But that's for each component. Surely you do other operations (like
> > difference in seconds) where the expressions are  far more complex?
>
> Actually, in this case, no. I leave it to Ada.Calendar. Convert,
> compute, convert. This limitation is documented.

Sounds nearly useless. Especially as Ada.Calendar.Time is a 64-bit type on
most compilers (but I realize you can't depend on that).

Even so, I'd expect that your equivelent of Time_Of would use a pretty
complex expression.

> > All-in-all, I prefer the record representation.
>
> For Calendar_64 I specifically wanted a 64-bit string, it was a
> requirement.

Yes, but that has nothing to do with whether it is represented as a record
or not. Just put a size clause on your record:

    for My_Time'Size use 64;

If you need an untyped blob for some reason, its easy enough to use an
Unchecked_Conversion. But it's often easy to avoid the need to have it
untyped in the first place -- we did that in many places in the Win32 calls
that underlie Claw.

> If I was to implement Ada.Calendar I think I would use a record too,
> because it is a private type by definition, so I would have to write
> the "<" functions anyway.
>
> > Janus/Ada Calendar.Time implementation is a 64-bit record type
>
> Just curious: is it aligned properly i.e. if you uncheckedly convert
> to a 64-bit modular will the modular "<" functions work properly i.e.
> represent the relations between the dates properly?

I think so, but it is a moot point: Janus/Ada doesn't (currently) support
any 64 bit integer or modular types. So you'd have to convert to a
Storage_Array or Stream_Array or similar.

> Of course a Calendar_64 for a specific compiler/platform could take
> advantage of the respective Ada.Calendar representation.

Yes, of course.

                               Randy.





^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: How do you bitwise operations in Ada '83 and '95
  2006-07-21 19:03           ` Simon Wright
@ 2006-07-22  8:32             ` Dmitry A. Kazakov
  2006-07-22  8:57               ` Simon Wright
  2006-07-22 10:52               ` Georg Bauhaus
  0 siblings, 2 replies; 49+ messages in thread
From: Dmitry A. Kazakov @ 2006-07-22  8:32 UTC (permalink / raw)


On Fri, 21 Jul 2006 20:03:09 +0100, Simon Wright wrote:

> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
> 
>> It depends on endianness. Provided that storage elements are octets
>> on both machines, which assumption could be wrong, 128 shifted left
>> might yield 0, 256 or even 64 (what is "left"?).
> 
> You might as well argue that the C operator<< could produce 64 or 256.

I can't tell for C. Does ANSI C standard require (x<<1) == (x*2)?

As for Ada 95, ARM certainly does not. This is why Shift_* is not portable.
Then Interfaces, where Shift_* is declared, does not refer to C, anyway.

>> When considering *any* thinkable architecture, it might be even
>> impossible to implement Shift_* at all. Let some crazy hardware
>> store numbers in only odd bits, reserving even ones for something
>> else (like a check-sum). On such imaginary hardware Shift_Left (*,
>> 1) wouldn't even yield a valid number! Actually "they operate on a
>> bit-by-bit basis" is quite hazy. What is bit? Which bits are
>> adjacent? How are they ordered? What does "left" mean? Which bits
>> are of the number? etc.
> 
> One would think the market for hardware like that would be pretty
> thin; not really a "thinkable" architecture. Certainly not
> interesting.

Ah, but the standard is silent about interesting vs. uninteresting bit
representations. Anyway, middle-endian machines still exist and produced.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: How do you bitwise operations in Ada '83 and '95
  2006-07-22  8:32             ` Dmitry A. Kazakov
@ 2006-07-22  8:57               ` Simon Wright
  2006-07-22 10:52               ` Georg Bauhaus
  1 sibling, 0 replies; 49+ messages in thread
From: Simon Wright @ 2006-07-22  8:57 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:

> I can't tell for C. Does ANSI C standard require (x<<1) == (x*2)?

From the Committee Draft WG14/N1124 of May 6 2005, p83, with minimal
editing,

4 The result of E1 << E2 is E1 left-shifted E2 bit positions; vacated
bits are filled with zeros. If E1 has an unsigned type, the value of
the result is E1�2^E2, reduced modulo one more than the maximum value
representable in the result type. If E1 has a signed type and
nonnegative value, and E1�2^E2 is representable in the result type,
then that is the resulting value; otherwise, the behavior is
undefined.
 
5 The result of E1 >> E2 is E1 right-shifted E2 bit positions. If E1
has an unsigned type or if E1 has a signed type and a nonnegative
value, the value of the result is the integral part of the quotient of
E1 / 2^E2. If E1 has a signed type and a negative value, the resulting
value is implementation-defined.



^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: How do you bitwise operations in Ada '83 and '95
  2006-07-22  8:32             ` Dmitry A. Kazakov
  2006-07-22  8:57               ` Simon Wright
@ 2006-07-22 10:52               ` Georg Bauhaus
  2006-07-22 13:31                 ` Dmitry A. Kazakov
  1 sibling, 1 reply; 49+ messages in thread
From: Georg Bauhaus @ 2006-07-22 10:52 UTC (permalink / raw)


On Sat, 2006-07-22 at 10:32 +0200, Dmitry A. Kazakov wrote:

>  Does ANSI C standard require (x<<1) == (x*2)?
> 
> As for Ada 95, ARM certainly does not. This is why Shift_* is not portable.

type Unsigned_n is mod 2**n;  -- Annex B.2

won't be portable for the same reason?

As for the bit representation of these intrinsic modular values,
wouldn't shift_left etc. have to provide a result that does
make sense, as per the AS-IF rule?






^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: How do you bitwise operations in Ada '83 and '95
  2006-07-22 10:52               ` Georg Bauhaus
@ 2006-07-22 13:31                 ` Dmitry A. Kazakov
  0 siblings, 0 replies; 49+ messages in thread
From: Dmitry A. Kazakov @ 2006-07-22 13:31 UTC (permalink / raw)


On Sat, 22 Jul 2006 12:52:29 +0200, Georg Bauhaus wrote:

> On Sat, 2006-07-22 at 10:32 +0200, Dmitry A. Kazakov wrote:
> 
>>  Does ANSI C standard require (x<<1) == (x*2)?
>> 
>> As for Ada 95, ARM certainly does not. This is why Shift_* is not portable.
> 
> type Unsigned_n is mod 2**n;  -- Annex B.2
> 
> won't be portable for the same reason?

Why? Semantics of modular arithmetic is defined in a portable way. As long
as you deal with *numbers* everything is OK.

> As for the bit representation of these intrinsic modular values,
> wouldn't shift_left etc. have to provide a result that does
> make sense, as per the AS-IF rule?

I am not a language lawyer. To me shifts aren't numeric operations, but
ones on arrays of bits. Mixing both is asking for trouble.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: How do you bitwise operations in Ada '83 and '95
  2006-07-21 19:09           ` Simon Wright
  2006-07-21 19:45             ` tmoran
@ 2006-07-23 15:59             ` Stephen Leake
  2006-07-24  6:08               ` Simon Wright
  1 sibling, 1 reply; 49+ messages in thread
From: Stephen Leake @ 2006-07-23 15:59 UTC (permalink / raw)


Simon Wright <simon@pushface.org> writes:

> Stephen Leake <stephen_leake@acm.org> writes, responding to me:
>
>>> I have a feeling that shift&mask ends up more understandable 
>>
>> Never.
>>
>>> and reviewable.
>>
>> In Ada 95, maybe. In Ada 2005, not.
>
> Really, understandable and reviewable are very similar, so I don't see
> how something could be (possibly) more reviewable while never more
> understandable.

Hmm. To me, "understandable" means "expressed in terms I am familiar
with, using idioms I am familiar with, and unambiguous". Or something
like that.

While "reviewable" means "traceable to source documentation".

So if I am familiar with the Ada 95 idiom for endianness-independent
rep clauses, they are "understandable". But because they are complex,
they may be less reviewable. I've never done a _formal_ review (trace to
source docs) of any software, so I'm on shaky ground here.

> Seriously, the C
>
>   field = (longword >> 15) & 0x3f;
>
> is pretty clear.

At the bit level, yes. But if the 7 bits are supposed to represent
some object, actual names would be far preferable.

-- 
-- Stephe



^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: How do you bitwise operations in Ada '83 and '95
  2006-07-23 15:59             ` Stephen Leake
@ 2006-07-24  6:08               ` Simon Wright
  0 siblings, 0 replies; 49+ messages in thread
From: Simon Wright @ 2006-07-24  6:08 UTC (permalink / raw)


Stephen Leake <stephen_leake@acm.org> writes:

> Simon Wright <simon@pushface.org> writes:
>
>> Stephen Leake <stephen_leake@acm.org> writes, responding to me:
>>
>>>> I have a feeling that shift&mask ends up more understandable 
>>>
>>> Never.
>>>
>>>> and reviewable.
>>>
>>> In Ada 95, maybe. In Ada 2005, not.
>>
>> Really, understandable and reviewable are very similar, so I don't
>> see how something could be (possibly) more reviewable while never
>> more understandable.
>
> Hmm. To me, "understandable" means "expressed in terms I am familiar
> with, using idioms I am familiar with, and unambiguous". Or
> something like that.
>
> While "reviewable" means "traceable to source documentation".
>
> So if I am familiar with the Ada 95 idiom for endianness-independent
> rep clauses, they are "understandable". But because they are
> complex, they may be less reviewable. I've never done a _formal_
> review (trace to source docs) of any software, so I'm on shaky
> ground here.

To me, code review is a process exceuted by people whose intention is
to ensure that the code does the right thing. Part of that is to check
that it's meeting its requirements, some of the requirements are
customer-imposed functional ones. So the people have to be able to
understand the code, and it helps if it's obviously doing the right
thing.

There are ways of writing Ada 95 rep clauses that were
endian-indepednent, I found them very clever but perhaps too clever.

>> Seriously, the C
>>
>>   field = (longword >> 15) & 0x3f;
>>
>> is pretty clear.
>
> At the bit level, yes. But if the 7 bits are supposed to represent
> some object, actual names would be far preferable.

I hope no one thought I was proposing that this bit twiddling (C or
Ada) should get out of package bodies!



^ permalink raw reply	[flat|nested] 49+ messages in thread

end of thread, other threads:[~2006-07-24  6:08 UTC | newest]

Thread overview: 49+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <1153244316.853254.291560@m79g2000cwm.googlegroups.com>
2006-07-18 18:45 ` How do you bitwise operations in Ada '83 and '95 Robert A Duff
2006-07-18 18:53 ` jimmaureenrogers
2006-07-18 19:22   ` Jeffrey R. Carter
2006-07-18 21:32     ` jimmaureenrogers
2006-07-19  0:40       ` Jeffrey R. Carter
2006-07-19  3:55         ` jimmaureenrogers
2006-07-19  4:37           ` Jeffrey R. Carter
2006-07-19 13:05             ` jimmaureenrogers
2006-07-19 19:43               ` Jeffrey R. Carter
2006-07-19 14:41             ` Robert A Duff
     [not found]             ` <1153313832.389434.144930@s13g2000cwa.googlegroups.com>
2006-07-19 13:55               ` Georg Bauhaus
2006-07-19 14:20               ` Robert A Duff
2006-07-19 19:30               ` Jeffrey R. Carter
2006-07-18 19:21 ` Jeffrey R. Carter
2006-07-19  3:01 ` tmoran
     [not found] <9315684D-C216-4EDA-8852-0A6BD4C275B0@amado-alves.info>
2006-07-19 22:30 ` Marius Amado-Alves
2006-07-20  7:40   ` Georg Bauhaus
2006-07-20  9:29     ` Colin Paul Gloster
2006-07-20 12:31       ` Georg Bauhaus
2006-07-20 13:08         ` Colin Paul Gloster
2006-07-20 13:29           ` Marius Amado-Alves
2006-07-20 13:49           ` Georg Bauhaus
2006-07-21  5:23             ` Colin Paul Gloster
2006-07-21  8:00               ` Georg Bauhaus
2006-07-20  9:03   ` Stephen Leake
2006-07-20  9:38     ` Marius Amado-Alves
2006-07-21  9:53       ` Stephen Leake
2006-07-20 11:31     ` Dmitry A. Kazakov
2006-07-20 13:18       ` Marius Amado-Alves
2006-07-21  9:58       ` Stephen Leake
2006-07-21 12:09         ` Dmitry A. Kazakov
2006-07-21 19:03           ` Simon Wright
2006-07-22  8:32             ` Dmitry A. Kazakov
2006-07-22  8:57               ` Simon Wright
2006-07-22 10:52               ` Georg Bauhaus
2006-07-22 13:31                 ` Dmitry A. Kazakov
2006-07-20  9:39 Fwd: " Marius Amado-Alves
2006-07-20 17:54 ` tmoran
2006-07-20 18:30   ` Marius Amado-Alves
2006-07-20 19:36     ` tmoran
2006-07-20 22:09       ` Simon Wright
2006-07-21 10:07         ` Stephen Leake
2006-07-21 19:09           ` Simon Wright
2006-07-21 19:45             ` tmoran
2006-07-23 15:59             ` Stephen Leake
2006-07-24  6:08               ` Simon Wright
     [not found] <BFF12262-F906-4F9A-B867-D0373609F038@amado-alves.info>
2006-07-20 16:40 ` Marius Amado-Alves
     [not found] <CD6E3BB8-52D2-4EED-A790-0184FE56A99A@amado-alves.info>
2006-07-20 20:41 ` Marius Amado-Alves
2006-07-20 23:13   ` Randy Brukardt
2006-07-21  5:38     ` Marius Amado-Alves
2006-07-21 22:09       ` Randy Brukardt

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