From: aratel@total.net (Andre Ratel)
Subject: Re: Ada vs Delphi?
Date: 1999/08/14
Date: 1999-08-14T00:00:00+00:00 [thread overview]
Message-ID: <37b54516.54588055@news.total.net> (raw)
In-Reply-To: 37B27FE8.6E09569E@Maths.UniNe.CH
My post is a bit long. I apologize, but I really want to get to the
bottom of this.
-=[Knowing the range]=----------
On Thu, 12 Aug 1999 10:03:52 +0200, Gautier
<Gautier.deMontmollin@Maths.UniNe.CH> wrote:
>Neither Delphi nor you can guess if the result of an expression
>like (n1 + n2) alone will be in some range.
It depends. More often than not, I use integers as counters.
For example, let's consider an hypothetical situation in which
we have the following loop
<<<
for n1:= -128 to 127
for n2:= -128 to 127
begin
sum:= n1 + n2;
...
end; {for}
>>>
We know the ranges of n1 and n2 and we have a pretty good idea
of the range of sum. Now, how do we declare these variables?
One way to do it, is to put all related variables in a same
set, chosen large enough to contain all their possible
values:
var
n1, n2, sum: integer;
The other would be to use smaller sets:
var
n1, n2: -128..127; {or equivalently: n1, n2: shorting;}
sum: integer;
With the latter declarations, we won't run into trouble if:
- the right-side of the expression is evaluated using the
largest set of integers (longint)
- the result is typecasted into the variable on the left-side
- some kind of error message pops up if one of the variable
gets outside its declared range.
When I began programming in Turbo Pascal, I tended to follow
this second approach but ran into all sorts of problems. Now,
apart from a few exceptional cases, I use integers or longints.
A safe language should be such that all evaluations are performed
using the largest set of numerals available (longint for integers,
extended for real numbers). The responsability of the programmer
would be then to choose the appropriate type of variables for
_storing_ the results in memory. (I am aware that this might lead
to problems in efficiency.)
Let's see if Turbo Pascal satisfies this safety requirement.
-=[Calculating with floating point]=----------
From the Turbo Pascal (v. 5) Reference Guide (pp. 185-186):
<<<
The extended type is the basis of all floating-point computations
with the 8087. Turbo Pascal uses the extended format to store
all non-integer numeric expressions using extended precision.
The entire right-side of the following assignment, for instance,
will be computed in extended before being converted to the type
on the left side:
{$N+} {using the numerical coprocessor}
var
X, A, B, C: real;
begin
X:= (B + Sqrt(B*B - A*C))/A;
end;
With no special effort by the programmer, Turbo Pascal performs
computations using the precision and range of the extended type.
The added precision means smaller round-off errors, and the
additional range means overflow and underflow are less common.
>>>
So, for floating points, everything seems safe enough.
-=[Calculating with integers]=----------
From the Reference Guide p. 26:
<<<
* The type with an integer constant is the predefined
integer with the smallest range that includes the value
of the integer constant.
* For all binary operators (an operator that takes two
operands), both operands are converted to their common
type before the operation. The _common_type_ is the
predefined integer type with the the smallest range that
includes all possible values of both types. For instance,
the common type of integer and byte is integer, and the
common type of integer and word is longint. The operation
is performed using the precision of the common type, and
the result type is the common type.
* The expresssion on the right of an assignment is evaluated
independently from the size or the type of the variable on
the left.
* Any byte sized operand is converted to an intermediate
word-sized type operand that is compatible with both
integer and word before any arithmetic operation is
performed.
>>>
So the problems of Turbo Pascal with integers arise from the
fact that, for the evaluation of expressions, the common type
is used instead of the largest set available (longint).
-=[Your example]=----------
I can now better understand the example you gave me.
<<<
{$R+}
var
n1, n2: shortint; {range: -128 .. 127}
i1,i2: integer; {range: -32768..32767}
N: longint; {range: -2147483648 .. 2147483647}
begin
n1:= 120;
n2:= 120;
N:= n1 + n2;
Writeln(N);
i1:= 32000;
i2:= 32000;
N:= i1 + i2;
Writeln(N);
end.
>>>
Since n1 and n2 are byte-sized, they are both converted to
word-sized and this is why, for (n1 + n2), we get the correct
result 240.
For (i1 + i2), the common type (integer) is used for the
evaluation and, since the sum is outside the range, we get
the wrong result -1536. This problem could be avoided if,
instead of using the common type, Turbo Pascal would use
longint.
I tried your example with Turbo Pascal 5 (I admit, at first,
I didn't believe the results and tought there was some
error in the listing). I also tried some variations on it.
First, I replaced the n1, n2, i1, and i2 declarations by
n1, n2: -128..127;
i1, i2: -32768..32767;
and, not surprisingly, got the same results (240 and -1536).
Now, what would happen if I declare i1 and i2 as constants:
<<<
{$R+}
const
i1 = 32000;
i2 = 32000;
var
n1, n2: shortint; {range: -128 .. 127}
N: longint; {range: -2147483648 .. 2147483647}
begin
n1:= 120;
n2:= 120;
N:= n1 + n2;
Writeln(N);
N:= i1 + i2;
Writeln(N);
N:= i1 - 5*i2; {here, I put something new}
Writeln(N);
end.
>>>
According to the first rule above, i1 and i2 should each be
casted as "integer with the smallest range that includes the
value of the integer constant". Since integer is the smallest
range including 32000, we should again get into trouble.
Surprisingly, when I run the above program, I get the correct
results:
240
64000
-128000
So, it seems, something is still escaping me. (On the other hand,
I'm glad that, here, we get the correct answers. Otherwise, using
constants would turn into a programming nightmare.)
-=[Handling types with Ada]=----------
Getting back to my first example:
<<<
for n1:= -128 to 127
for n2:= -128 to 127
begin
sum:= n1 + n2;
...
end; {for}
>>>
how would you declare variables n1, n2, and sum in Ada?
> In Ada you can handle ranges and bits independently:
> e.g. a 32-bit subtype of range -127..128, etc. etc.
> In the same subtype family (e.g. integer, natural, positive)
> you can write n1+n2 safely, without explicit conversion, as
> there is no bad surprise with hidden type conversions; ranges
> will be checked correctly - provided you didn't suppress them
> at compile time...
This is new to me. I've never seen something like this in the
languages I used before (Fortran 77, Pascal, C, IDL). I think
I'm beginning to get the idea but I would appreciate a small
example of this, just to see how this looks like in Ada.
Andre
PS: Thanks to all those who participate in this exchange. I really
appreciate the input.
next prev parent reply other threads:[~1999-08-14 0:00 UTC|newest]
Thread overview: 49+ messages / expand[flat|nested] mbox.gz Atom feed top
1999-08-06 0:00 Ada vs Delphi? Andre Ratel
1999-08-06 0:00 ` Steve Doiel
1999-08-09 0:00 ` Paul Groves
1999-08-08 0:00 ` Steve Doiel
1999-08-10 0:00 ` Ray Blaak
1999-08-10 0:00 ` Steve Doiel
1999-08-14 0:00 ` Andre Ratel
1999-08-09 0:00 ` Robert Dewar
1999-08-11 0:00 ` Andre Ratel
1999-08-11 0:00 ` Ted Dennison
1999-08-14 0:00 ` Andre Ratel
1999-08-16 0:00 ` Ted Dennison
1999-08-11 0:00 ` Robert Dewar
1999-08-14 0:00 ` Andre Ratel
1999-08-17 0:00 ` Robert I. Eachus
1999-08-11 0:00 ` Robert Dewar
1999-08-11 0:00 ` David Botton
1999-08-14 0:00 ` Andre Ratel
1999-08-09 0:00 ` Aidan Skinner
1999-08-09 0:00 ` Robert Dewar
1999-08-09 0:00 ` Gautier
1999-08-11 0:00 ` Andre Ratel
1999-08-12 0:00 ` Gautier
1999-08-12 0:00 ` Gautier
1999-08-14 0:00 ` Andre Ratel [this message]
1999-08-14 0:00 ` Gautier
1999-08-16 0:00 ` Gautier
1999-08-15 0:00 ` Steve Doiel
1999-08-17 0:00 ` Robert I. Eachus
1999-08-10 0:00 ` Brian Rogoff
1999-08-11 0:00 ` Scientific calculations (was Re: Ada vs Delphi? ) Vladimir Olensky
1999-08-11 0:00 ` Robert Dewar
1999-08-11 0:00 ` Robert Dewar
1999-08-11 0:00 ` Vladimir Olensky
1999-08-13 0:00 ` Robert Dewar
1999-08-13 0:00 ` Brian Rogoff
1999-08-15 0:00 ` Vladimir Olensky
1999-08-15 0:00 ` Vladimir Olensky
1999-08-13 0:00 ` Gautier
1999-08-11 0:00 ` Ada vs Delphi? Andre Ratel
1999-08-11 0:00 ` Ada vs Component Pascal (was: Ada vs Delphi?) Ted Dennison
1999-08-11 0:00 ` Ada vs Delphi? Robert Dewar
1999-08-14 0:00 ` Andre Ratel
1999-08-06 0:00 ` William Starner
1999-08-06 0:00 ` William Starner
1999-08-07 0:00 ` tmoran
1999-08-07 0:00 ` Aidan Skinner
1999-08-07 0:00 ` Gautier
1999-08-07 0:00 ` Gautier
replies disabled
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox