comp.lang.ada
 help / color / mirror / Atom feed
* The right way to handle this difference in Ada
@ 2004-07-22 10:23 vic
  2004-07-22 11:53 ` Eric Jacoboni
                   ` (5 more replies)
  0 siblings, 6 replies; 12+ messages in thread
From: vic @ 2004-07-22 10:23 UTC (permalink / raw)


Hello,

I'm starting to develope in Ada 95, but as I come from C++ language I'm
having some difficulties about strong typing.


Please consider this type:

type unsigned_int_12_type is range 0..(2*12)-1;

and these 2 variables of the above type:

a: unsigned_int_12_type;
b: unsigned_int_12_type;

If the code must perform a difference between a and b, say:

c := a-b

1) which should be the type of c? I think it should be something like:

type signed_int_12_type is range -unsigned_int_12'last ..
unsigned_int_12'last.

Is this right?

2) And I should rename a "-" operation which gets two signed_int_12_type  as
operands and returns signed_int_12_type as result?


Thanks,

vic





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

* Re: The right way to handle this difference in Ada
  2004-07-22 10:23 The right way to handle this difference in Ada vic
@ 2004-07-22 11:53 ` Eric Jacoboni
  2004-07-22 12:07 ` Nick Roberts
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 12+ messages in thread
From: Eric Jacoboni @ 2004-07-22 11:53 UTC (permalink / raw)


"vic" <ppp@ppp.it> writes:

> type unsigned_int_12_type is range 0..(2*12)-1;

I guess you wanted to say:

type unsigned_int_12_type is range 0..(2**12)-1;
for unsigned_int_12_type'Size use 12;

> and these 2 variables of the above type:
>
> a: unsigned_int_12_type;
> b: unsigned_int_12_type;
>
> If the code must perform a difference between a and b, say:
>
> c := a-b
>
> 1) which should be the type of c? I think it should be something like:

C can be a unsigned_int_12_type, as (a - b) _is_ a unsigned_int_12_type
(at least, i guess). Of course, if b > a, execution will raise a
Constraint_Error...

But, as far i've understood, you want to allow situations where b > a ?

type Unsigned_Int_12_Type is mod 2**12;
for Unsigned_Int_12_Type'size use 12;

type Int_12_Type is -(2**11)..+(2**11) - 1;
for Int_12_Type'size use 12;

C : Int_12_Type;
A, B : Unsigned_Int_12_Type;

A := 10; B := 12;
C := Int_12_Type(A - B);  -- C = -2


> type signed_int_12_type is range -unsigned_int_12'last ..
> unsigned_int_12'last.

> Is this right?

No, if unsigned is 0..2^n - 1, signed should be -2^(n-1)..+2^(n-1) - 1


> 2) And I should rename a "-" operation which gets two signed_int_12_type  as
> operands and returns signed_int_12_type as result?

like this :

function "-"(A, B : in Unsigned_Int_12_Type) return Int_12_Type;


-- 
�ric Jacoboni, n� il y a 1393940281 secondes



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

* Re: The right way to handle this difference in Ada
  2004-07-22 10:23 The right way to handle this difference in Ada vic
  2004-07-22 11:53 ` Eric Jacoboni
@ 2004-07-22 12:07 ` Nick Roberts
  2004-07-22 13:03 ` Dmitry A. Kazakov
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 12+ messages in thread
From: Nick Roberts @ 2004-07-22 12:07 UTC (permalink / raw)


On Thu, 22 Jul 2004 12:23:09 +0200, vic <ppp@ppp.it> wrote:

> Please consider this type:
>
> type unsigned_int_12_type is range 0..(2*12)-1;
>
> and these 2 variables of the above type:
>
> a: unsigned_int_12_type;
> b: unsigned_int_12_type;
>
> If the code must perform a difference between a and b, say:
>
> c := a-b
>
> 1) which should be the type of c? I think it should be
> something like:
>
> type signed_int_12_type is range -unsigned_int_12'last ..
> unsigned_int_12'last.
>
> Is this right?

I'm guessing that what you really require is to be able to
pack one or more 12-bit integers into a record. Is this
correct?

If it is, the solution to your problem is likely to be this:

    subtype My_Integer is Integer range 0..2**12-1;

    A, B: My_Integer;

    C: Integer range -My_Integer'Last..My_Integer'Last;

    ...

    C := A-B;

    ...

    type My_Record is
       record
          ...
          X, Y: My_Integer;
          ...
       end record;

    for My_Record use
       record
          ...
          X     at 5 range 0..11;
          Y     at 5 range 12..23;
          ...
       end record;

The idea is that you use a standard base type for the
arithmetic, declaring subtypes which restrict the range
as appropriate, and then tell the compiler explicitly
how to squeeze values into 12-bit parts of the record
type. With luck, the compiler will oblige (or tell you
why it cannot).

Des this help?

> 2) And I should rename a "-" operation which gets two signed_int_12_type  
> as operands and returns
> signed_int_12_type as result?

Hopefully the above technique will work for you, and
enable to avoid the need to declare your own arithmetic
operations.

-- 
Nick Roberts



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

* Re: The right way to handle this difference in Ada
  2004-07-22 10:23 The right way to handle this difference in Ada vic
  2004-07-22 11:53 ` Eric Jacoboni
  2004-07-22 12:07 ` Nick Roberts
@ 2004-07-22 13:03 ` Dmitry A. Kazakov
  2004-07-22 13:22   ` Eric Jacoboni
  2004-07-22 13:34 ` Björn Persson
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 12+ messages in thread
From: Dmitry A. Kazakov @ 2004-07-22 13:03 UTC (permalink / raw)


On Thu, 22 Jul 2004 12:23:09 +0200, vic wrote:

> Hello,
> 
> I'm starting to develope in Ada 95, but as I come from C++ language I'm
> having some difficulties about strong typing.
> 
> Please consider this type:
> 
> type unsigned_int_12_type is range 0..(2*12)-1;
> 
> and these 2 variables of the above type:
> 
> a: unsigned_int_12_type;
> b: unsigned_int_12_type;
> 
> If the code must perform a difference between a and b, say:
> 
> c := a-b
> 
> 1) which should be the type of c? I think it should be something like:
> 
> type signed_int_12_type is range -unsigned_int_12'last ..
> unsigned_int_12'last.
> 
> Is this right?

It depends!

1. In C++ spirit I would expect something like

   type unsigned_int_12_type is mod 2**12;

and the types of a,b,c all same. So that:

   a : unsigned_int_12_type := 1;
   b : unsigned_int_12_type := 2;
   c : unsigned_int_12_type := a - b; -- yields 4095

2. Well, if c should be negative then probably:

   type int_12_type is range -2**12..2**12-1;
   subtype unsigned_int_12_subtype is
      int_12_type range 0..int_12_type'Last;

   a : unsigned_int_12_subtype := 1;
   b : unsigned_int_12_subtype := 2;
   c : int_12_type := a - b; -- yields -1

Here unsigned_int_12_subtype is a subtype. Though its values cannot be
negative, temporary values can be. It is similar to the solution of
proposed by Nick Roberts, but uses a separate type int_12_type instead of
standard Integer, mainly for strong typing sake.

> 2) And I should rename a "-" operation which gets two signed_int_12_type  as
> operands and returns signed_int_12_type as result?

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



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

* Re: The right way to handle this difference in Ada
  2004-07-22 13:03 ` Dmitry A. Kazakov
@ 2004-07-22 13:22   ` Eric Jacoboni
  2004-07-22 13:34     ` Dmitry A. Kazakov
  0 siblings, 1 reply; 12+ messages in thread
From: Eric Jacoboni @ 2004-07-22 13:22 UTC (permalink / raw)


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


> 2. Well, if c should be negative then probably:
>
>    type int_12_type is range -2**12..2**12-1;
>    subtype unsigned_int_12_subtype is
>       int_12_type range 0..int_12_type'Last;
>
>    a : unsigned_int_12_subtype := 1;
>    b : unsigned_int_12_subtype := 2;
>    c : int_12_type := a - b; -- yields -1

Perhaps i've not understood all the implications of the initial
question but, imo, a signed int_n_type varies from -2**(n - 1) to
+2**(n - 1) - 1, not from -2**n to +2**n - 1.

-- 
�ric Jacoboni, n� il y a 1393946375 secondes



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

* Re: The right way to handle this difference in Ada
  2004-07-22 13:22   ` Eric Jacoboni
@ 2004-07-22 13:34     ` Dmitry A. Kazakov
  0 siblings, 0 replies; 12+ messages in thread
From: Dmitry A. Kazakov @ 2004-07-22 13:34 UTC (permalink / raw)


On Thu, 22 Jul 2004 15:22:24 +0200, Eric Jacoboni wrote:

> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
> 
>> 2. Well, if c should be negative then probably:
>>
>>    type int_12_type is range -2**12..2**12-1;
>>    subtype unsigned_int_12_subtype is
>>       int_12_type range 0..int_12_type'Last;
>>
>>    a : unsigned_int_12_subtype := 1;
>>    b : unsigned_int_12_subtype := 2;
>>    c : int_12_type := a - b; -- yields -1
> 
> Perhaps i've not understood all the implications of the initial
> question but, imo, a signed int_n_type varies from -2**(n - 1) to
> +2**(n - 1) - 1, not from -2**n to +2**n - 1.

So let n=13 (:-))

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



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

* Re: The right way to handle this difference in Ada
  2004-07-22 10:23 The right way to handle this difference in Ada vic
                   ` (2 preceding siblings ...)
  2004-07-22 13:03 ` Dmitry A. Kazakov
@ 2004-07-22 13:34 ` Björn Persson
  2004-07-22 17:52 ` Georg Bauhaus
  2004-07-23  3:41 ` Steve
  5 siblings, 0 replies; 12+ messages in thread
From: Björn Persson @ 2004-07-22 13:34 UTC (permalink / raw)


vic wrote:

> a: unsigned_int_12_type;
> b: unsigned_int_12_type;
> 
> If the code must perform a difference between a and b, say:
> 
> c := a-b
> 
> 1) which should be the type of c? I think it should be something like:
> 
> type signed_int_12_type is range -unsigned_int_12'last ..
> unsigned_int_12'last.

It all depends on what values are sensible for c to have. If for example 
c should never be negative, then it's an error if b is greater than a in 
the subtraction. Then you can declare c as unsigned_int_12_type, and if 
the subtraction ever yields a negative value you'll get a Constraint_Error.

-- 
Björn Persson                              PGP key A88682FD
                    omb jor ers @sv ge.
                    r o.b n.p son eri nu




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

* Re: The right way to handle this difference in Ada
  2004-07-22 10:23 The right way to handle this difference in Ada vic
                   ` (3 preceding siblings ...)
  2004-07-22 13:34 ` Björn Persson
@ 2004-07-22 17:52 ` Georg Bauhaus
  2004-07-22 18:10   ` Georg Bauhaus
  2004-07-23  3:41 ` Steve
  5 siblings, 1 reply; 12+ messages in thread
From: Georg Bauhaus @ 2004-07-22 17:52 UTC (permalink / raw)


vic <ppp@ppp.it> wrote:
: 
: 
: Please consider this type:
: 
: type unsigned_int_12_type is range 0..(2*12)-1;

A step forward towards an Ada solution is stating
what you need this type for. So for what are objects of
this type used?

It is likely easier then for people to hint at
a language representation that suits your needs.
If you just "port" the C++ solution to what you think
is the "same" Ada solution, you might miss valuable
facilities of Ada. Coding might also become much more
difficult than it needs to be.

: c := a-b
: 
: 1) which should be the type of c? I think it should be something like:

What it should be depends what c is supposed to be.
For example, if you calculate in units of apples, then
  "a apples - b apples"
cannot easily be a sensible expression if a > b,
numerically. So what is c supposed to be?

If you include debt (in apples) then c might be the
number of apples that someone owes someone else.
So there exists a common "counting type" for the
number a, b, and c. In this case I'd choose a reasonable
range for possible numbers of apples, say

  type Apple_Count is range -10_000 .. 20_000;

and then, for measuring existing apples,

  subtype Existing_Apples is Apple_Count range 0 .. Apple_Count'last;

(There are no negative number included since obviously
there are no apples that don't exist.) Then,

  c: Apple_Count;
  a, b: Existing_Apples;

  ...

  c := a - b;

Or do you need 12 bits for some hardware representation?
In this case you can use a modular type as has been demonstrated
in another response, a packed array of Boolean values,
or a record with a representation clause (similar to a
bitfield in C.)

: 2) And I should rename a "-" operation which gets two signed_int_12_type  as
: operands and returns signed_int_12_type as result?

If you want "-" to convert to the type of c, I think it might help
the reader of the source code if instead you convert the
operands so that "-" becomes a computation in the type of c.


-- Georg



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

* Re: The right way to handle this difference in Ada
  2004-07-22 17:52 ` Georg Bauhaus
@ 2004-07-22 18:10   ` Georg Bauhaus
  0 siblings, 0 replies; 12+ messages in thread
From: Georg Bauhaus @ 2004-07-22 18:10 UTC (permalink / raw)


Georg Bauhaus <sb463ba@l1-hrz.uni-duisburg.de> wrote:

: cannot easily be a sensible expression if a > b,

Argh. a < b, of course.




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

* Re: The right way to handle this difference in Ada
  2004-07-22 10:23 The right way to handle this difference in Ada vic
                   ` (4 preceding siblings ...)
  2004-07-22 17:52 ` Georg Bauhaus
@ 2004-07-23  3:41 ` Steve
  2004-07-23 12:47   ` Marius Amado Alves
  5 siblings, 1 reply; 12+ messages in thread
From: Steve @ 2004-07-23  3:41 UTC (permalink / raw)


When programming in C/C++ you think in terms of the small fixed set of data
types that map to the hardware...

C/C++ thinking:
  Let's see... I have a value that is going to be in the range of 0 to 457.
That means I'll need to use a 16 bit value.  I'll use a short or an unsigned
short, since I know that on the machine I am programming, short values are
16 bit.

Ada thinking:
  Let's see... I have a value that is going to be in the range of 0 to 457.
I'll define a tyhpe and let the compiler worry about it.

  type My_Type is range 0 .. 457;

  The only time you really need to worry about the number of bits is when
you are programming interfaces.

  Back to your question.  Your question leads to another question: what
should happen if I subtract two variables of type unsigned_int_12_type?

  If you want the values to "wrap" like unsigned values in C++, you should
define your type using a "mod" type instead.  If the result of your
subraction is always going to be a signed value in the range of
unsigned_int_12_type, then go ahead and define c as an unsigned_int_12_type.
If the difference is out of range, you'll get a runtime error.

 Since you indicated your background is C++, I'm guessing you want the type
to behave more like an unsigned value in C++ and ignore out of range
conditions.  If that is the case, change your definition to:

  type unsigned_int_12_type is mod 2**12;

  And define c of the same type.

Steve
(The Duck)

"vic" <ppp@ppp.it> wrote in message news:cdo4ic$q8f$1@e3k.asi.ansaldo.it...
> Hello,
>
> I'm starting to develope in Ada 95, but as I come from C++ language I'm
> having some difficulties about strong typing.
>
>
> Please consider this type:
>
> type unsigned_int_12_type is range 0..(2*12)-1;
>
> and these 2 variables of the above type:
>
> a: unsigned_int_12_type;
> b: unsigned_int_12_type;
>
> If the code must perform a difference between a and b, say:
>
> c := a-b
>
> 1) which should be the type of c? I think it should be something like:
>
> type signed_int_12_type is range -unsigned_int_12'last ..
> unsigned_int_12'last.
>
> Is this right?
>
> 2) And I should rename a "-" operation which gets two signed_int_12_type
as
> operands and returns signed_int_12_type as result?
>
>
> Thanks,
>
> vic
>
>





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

* Re: The right way to handle this difference in Ada
  2004-07-23  3:41 ` Steve
@ 2004-07-23 12:47   ` Marius Amado Alves
  2004-07-24  3:14     ` Robert I. Eachus
  0 siblings, 1 reply; 12+ messages in thread
From: Marius Amado Alves @ 2004-07-23 12:47 UTC (permalink / raw)
  To: comp.lang.ada

Steve wrote:

> When programming in C/C++ you think in terms of the small fixed set of data
> types that map to the hardware...
> 
> C/C++ thinking:
>   Let's see... I have a value that is going to be in the range of 0 to 457.
> That means I'll need to use a 16 bit value.  I'll use a short or an unsigned
> short, since I know that on the machine I am programming, short values are
> 16 bit.
> 
> Ada thinking:
>   Let's see... I have a value that is going to be in the range of 0 to 457.
> I'll define a tyhpe and let the compiler worry about it.
> 
>   type My_Type is range 0 .. 457;
> 
>   The only time you really need to worry about the number of bits is when
> you are programming interfaces.

This is wise advice up until here. Original Poster, follow it. Welcome 
to the Ada Way.

>   Back to your question.  Your question leads to another question: what
> should happen if I subtract two variables of type unsigned_int_12_type?

No. You should ask: why do I want to subtract? What is the resulting 
type? An intermediary value in an expression? A definitive value? Of 
what type?

>   If you want the values to "wrap" like unsigned values in C++, you should
> define your type using a "mod" type instead.  If the result of your
> subraction is always going to be a signed value in the range of
> unsigned_int_12_type, then go ahead and define c as an unsigned_int_12_type.
> If the difference is out of range, you'll get a runtime error.
> 
>  Since you indicated your background is C++, I'm guessing you want the type
> to behave more like an unsigned value in C++ and ignore out of range
> conditions.  If that is the case, change your definition to:
> 
>   type unsigned_int_12_type is mod 2**12;
> 
>   And define c of the same type...

For some reason in this part of the reply Steve has regressed to what he 
himself calls "C/C++ thinking". Original Poster, ignore.





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

* Re: The right way to handle this difference in Ada
  2004-07-23 12:47   ` Marius Amado Alves
@ 2004-07-24  3:14     ` Robert I. Eachus
  0 siblings, 0 replies; 12+ messages in thread
From: Robert I. Eachus @ 2004-07-24  3:14 UTC (permalink / raw)


Marius Amado Alves wrote:

> For some reason in this part of the reply Steve has regressed to what he 
> himself calls "C/C++ thinking". Original Poster, ignore.

I think Steve admitted as much:

>  Since you indicated your background is C++, I'm guessing you want the type
> to behave more like an unsigned value in C++ and ignore out of range
> conditions.  If that is the case, change your definition to...

There are cases where an Ada programmer will use a modular type, because 
modular behavior is desired.  Marius' point is that not wanting to think 
about error conditions is poor Ada practice, I assume, not that modular 
types should be considered evil.

-- 

                                           Robert I. Eachus

"The flames kindled on the Fourth of July, 1776, have spread over too 
much of the globe to be extinguished by the feeble engines of despotism; 
on the contrary, they will consume these engines and all who work them." 
-- Thomas Jefferson, 1821




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

end of thread, other threads:[~2004-07-24  3:14 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-07-22 10:23 The right way to handle this difference in Ada vic
2004-07-22 11:53 ` Eric Jacoboni
2004-07-22 12:07 ` Nick Roberts
2004-07-22 13:03 ` Dmitry A. Kazakov
2004-07-22 13:22   ` Eric Jacoboni
2004-07-22 13:34     ` Dmitry A. Kazakov
2004-07-22 13:34 ` Björn Persson
2004-07-22 17:52 ` Georg Bauhaus
2004-07-22 18:10   ` Georg Bauhaus
2004-07-23  3:41 ` Steve
2004-07-23 12:47   ` Marius Amado Alves
2004-07-24  3:14     ` Robert I. Eachus

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