Error #215 Arithmetic overflow, where it shouldn′t occur(?)
Author Message
Error #215 Arithmetic overflow, where it shouldn′t occur(?)

Hello you all,

i am currently thinking about the following program, and i would be
glad if anybody could tell me how the error can be avoided  ...besides
Q-R-... and what causes it.

greetings, Michael

nb. TP 7.01, free french version form inprise.

Program Err215;

Var   h,m,s : Integer;
n : LongInt;

{\$Q+}
{\$R+}

Begin

n:=16*3600+22*60+16;       { =58936, as expected }

h:=16;
m:=22;
s:=16;

n:=h*3600+m*60+s;          {Error 215}

End.

Sat, 19 Jul 2003 02:17:38 GMT
Error #215 Arithmetic overflow, where it shouldn′t occur(?)

Quote:
>    Program Err215;

>    Var   h,m,s : Integer;
>              n : LongInt;

>    {\$Q+}
>    {\$R+}

>    Begin

>      n:=16*3600+22*60+16;       { =58936, as expected }

>      h:=16;
>      m:=22;
>      s:=16;

>      n:=h*3600+m*60+s;          {Error 215}

Typecast h as longint. TP does normally arithmetic with 16-bits. It
cannot guess that in the particular case it might overflow and therefore
decide to use 32-bit arithmetic. You have to tell that to it:

n:=longint(h)*3600+m*60+s;

Alternatively you could just define h as a longint. The m and s do not
matter as once the type switches to longint the rest is longint and
m*60 cannot overflow.

Or you could always do ASM

asm
mov ax,60
mul m
mov bx,ax

mov ax,3600
mul h
add ax,bx
adc dx,0
add ax,s
adc dx,0
mov word ptr n,ax
mov word ptr n+2,dx
end;
:-)

Osmo

Sat, 19 Jul 2003 02:49:20 GMT
Error #215 Arithmetic overflow, where it shouldn′t occur(?)

Quote:

> Hello you all,

> i am currently thinking about the following program, and i would be
> glad if anybody could tell me how the error can be avoided  ...besides
> Q-R-... and what causes it.

> greetings, Michael

> nb. TP 7.01, free french version form inprise.

>     Program Err215;

>     Var   h,m,s : Integer;
>               n : LongInt;

>     {\$Q+}
>     {\$R+}

>     Begin

>       n:=16*3600+22*60+16;       { =58936, as expected }

>       h:=16;
>       m:=22;
>       s:=16;

>       n:=h*3600+m*60+s;          {Error 215}

>     End.

Hi

You have found one drawback to automatic numeric type conversions.
The problem is in h*3600. 16*3600 is computed as a longint because the
result type is a longint. However each product in h*3600 +m*60+ s is
computed as an integer and in this case h*3600 is out of range.

Assuming m <= 60 (so that m*60<maxint) n:= longint (h) * 3600 + m*60 + s
will solve your problem.

to be absolutely positively sure use n:= longint (h)*3600+longint (m)*60
+longint (s), although this is probably overkill .

Regards Hanford

Sat, 19 Jul 2003 02:52:36 GMT
Error #215 Arithmetic overflow, where it shouldn′t occur(?)

Quote:
> Hello you all,

> i am currently thinking about the following program, and i would be
> glad if anybody could tell me how the error can be avoided  ...besides
> Q-R-... and what causes it.

> greetings, Michael

> nb. TP 7.01, free french version form inprise.

>     Program Err215;

>     Var   h,m,s : Integer;
>               n : LongInt;

>     {\$Q+}
>     {\$R+}

>     Begin

>       n:=16*3600+22*60+16;       { =58936, as expected }

>       h:=16;
>       m:=22;
>       s:=16;

>       n:=h*3600+m*60+s;          {Error 215}

>     End.

Have you tried replacing n:=h*3600+m*60+s;  with:
n:=h*3600;
n:=n+m*60+s;
(I don't know what a Error 215 is, but you are multiplying an
integer (h) * 3600 which may generate an answer outside the range of an
integer, and it has to be temporarily stored whilst evaluating the 2nd
half of the expression - the two statements store the long-val in the
long-int, then adds the rest. You could also try reversing the
assignment so:
n:=m*60+s+h*3600;

Sent via Deja.com
http://www.deja.com/

Sat, 19 Jul 2003 02:51:43 GMT
Error #215 Arithmetic overflow, where it shouldn′t occur(?)

Quote:

>Have you tried replacing n:=h*3600+m*60+s;  with:
>       n:=h*3600;
>       n:=n+m*60+s;
>   (I don't know what a Error 215 is, but you are multiplying an
>integer (h) * 3600 which may generate an answer outside the range of an
>integer, and it has to be temporarily stored whilst evaluating the 2nd
>half of the expression - the two statements store the long-val in the
>long-int, then adds the rest. You could also try reversing the
>assignment so:
>          n:=m*60+s+h*3600;

Sorry, none of these changes do change anything.
As Hanford Carr posted, the problem is (h*3600), regardless of its
whens and wheres.
Thank you nevertheless.

Sat, 19 Jul 2003 04:04:12 GMT
Error #215 Arithmetic overflow, where it shouldn′t occur(?)

Quote:
>Assuming m <= 60 (so that m*60<maxint) n:= longint (h) * 3600 + m*60 + s
>will solve your problem.

You assumed correctly :-)

Quote:
>to be absolutely positively sure use n:= longint (h)*3600+longint (m)*60
>+longint (s), although this is probably overkill .

In my particular case, it would of course be overkill.
Anyway, good to know a bit more about how TP does arithmetics, and
ill keep this in mind.

Thank you

Michael

Quote:
>Regards Hanford

Sat, 19 Jul 2003 04:04:20 GMT
Error #215 Arithmetic overflow, where it shouldn′t occur(?)

Quote:
>Typecast h as longint. TP does normally arithmetic with 16-bits. It
>cannot guess that in the particular case it might overflow and therefore
>decide to use 32-bit arithmetic. You have to tell that to it:

>      n:=longint(h)*3600+m*60+s;

Thank you, too.

Quote:
>Alternatively you could just define h as a longint. The m and s do not
>matter as once the type switches to longint the rest is longint and
>m*60 cannot overflow.

Sorry, i tried it, and it wont work on my side.

If i do

n:=longint(h)*3600+m*3600+s

TP wont do it. I have to explicitly announce a LongInt-result each
time ( longint(m)*3600 ) or define the variables as LongInts right
away.

Quote:
>Or you could always do ASM

>     asm
>     mov ax,60
>     mul m
>     mov bx,ax

>     mov ax,3600
>     mul h
>     add ax,bx
>     adc dx,0
>     add ax,s
>     adc dx,0
>     mov word ptr n,ax
>     mov word ptr n+2,dx
>     end;
>:-)

??? - to deep inside for me :-)

Thanks again, Michael

Sat, 19 Jul 2003 04:04:22 GMT
Error #215 Arithmetic overflow, where it shouldn′t occur(?)

Quote:

> >    Program Err215;

> >    Var   h,m,s : Integer;
> >              n : LongInt;

> >    {\$Q+}
> >    {\$R+}

> >    Begin

> >      n:=16*3600+22*60+16;       { =58936, as expected }

> >      h:=16;
> >      m:=22;
> >      s:=16;

> >      n:=h*3600+m*60+s;          {Error 215}

> ...
> Alternatively you could just define h as a longint. The m and s do not
> matter as once the type switches to longint the rest is longint and
> m*60 cannot overflow.
> ...
> :-)

> Osmo

Hi

Using BP7 I just tried n:= longint (h)*3600 +m*60 + s everything the
same except m:=1000. This resulted in arithmetic overflow. Also I tried
switching h to a longint with m left as an integer and equal to 1000 and
that also resulted in a #215. Apparently the compiler doesn't
automatically switch the factors of other terms to longint before
calculating the other terms but only the results of each term (if it's
not already the right type).

I believe that Borland changed the way these expressions are evaluated.
Formerly longint (h) may have forced the rest but now it doesn't. I
recall having code that worked fine until I upgraded, then it didn't. It
was a matter of adding typecasts to integer types. I'd like to try this
in tp5 or tp55 but I'd have to find my old disks. Anybody curious?

Regards Hanford

Sat, 19 Jul 2003 03:39:45 GMT
Error #215 Arithmetic overflow, where it shouldn′t occur(?)

Hello again :-)

Quote:
>I believe that Borland changed the way these expressions are evaluated.
>Formerly longint (h) may have forced the rest but now it doesn't. I
>recall having code that worked fine until I upgraded, then it didn't. It
>was a matter of adding typecasts to integer types. I'd like to try this
>in tp5 or tp55 but I'd have to find my old disks. Anybody curious?

Ive been curious enough and found a TP5.5 on my harddisk.

While, in this i did not find the \$Q-directive, and more i found,
that, unless you explicitly say LongInt(h) TP5.5 does not report any
error, but gives -6600 as wrong result.

Michael

Sat, 19 Jul 2003 05:16:40 GMT
Error #215 Arithmetic overflow, where it shouldn′t occur(?)

Quote:

>> ...
>> Alternatively you could just define h as a longint. The m and s do not
>> matter as once the type switches to longint the rest is longint and
>> m*60 cannot overflow.
>> ...
>> :-)

>> Osmo

>Hi

>Using BP7 I just tried n:= longint (h)*3600 +m*60 + s everything the
>same except m:=1000. This resulted in arithmetic overflow.

On what planet there are 1000 minutes in a hour??? Of course you can
make any multiplication overflow if you put large enough values.,

Quote:
> Also I tried
>switching h to a longint with m left as an integer and equal to 1000 and
>that also resulted in a #215. Apparently the compiler doesn't
>automatically switch the factors of other terms to longint before
>calculating the other terms but only the results of each term (if it's
>not already the right type).

I do not understand what you say but TP is a 16-bit compiler. It uses
16-bit operations whenever possible. If this then results in an
overflow, it results in an overflow. The reason for this is that
16-bit operations are much much much faster. However, in case of
multiplication the 16-bit multiplication results in a 32-bit value.  A
HLL like Pascal expects result to be same type as the operation so it
does not use the 16-bit value.

Here is a small inline function which does fast 16bit*16bit=32bit
multiplication:

Function Imul(x,y:integer):longint;
inline(
\$5B/              {POP     BX}
\$58/              {POP     AX}
\$F7/\$EB           {IMUL    BX}
);

So you could write:;

Imul(h,3600)+Imul(m,60)+s

Quote:
>I believe that Borland changed the way these expressions are evaluated.
>Formerly longint (h) may have forced the rest but now it doesn't.

It forces the rest on the lower levels. That it forces the
multiplication and the following additions into longint but if of course
does not force the other multiplication. It would be a bug if it
affected that code.

Osmo

Sat, 19 Jul 2003 05:09:19 GMT
Error #215 Arithmetic overflow, where it shouldn′t occur(?)

Wed, 18 Jun 1902 08:00:00 GMT
Error #215 Arithmetic overflow, where it shouldn′t occur(?)

Quote:
>You have found one drawback to automatic numeric type conversions.
>The problem is in h*3600. 16*3600 is computed as a longint because the
>result type is a longint.

Actually that is not the reason. The reason is that the compiler uses
32 bits for the calculations.

var x:word;

Begin
x:=(60000+60000) div 2;
Writeln(x);
End.

Outputs 60000 which shows that the calculation is done with 32 bits.

Osmo

Sat, 19 Jul 2003 05:17:06 GMT
Error #215 Arithmetic overflow, where it shouldn′t occur(?)

Wed, 18 Jun 1902 08:00:00 GMT
Error #215 Arithmetic overflow, where it shouldn′t occur(?)

Quote:

>If i do

>  n:=longint(h)*3600+m*3600+s

That is garbage. Minutes are not same as hours. If you code garbage,
you can get errors.

Osmo

Sat, 19 Jul 2003 05:10:43 GMT
Error #215 Arithmetic overflow, where it shouldn′t occur(?)

Quote:

> >Typecast h as longint. TP does normally arithmetic with 16-bits. It
> >cannot guess that in the particular case it might overflow and
therefore
> >decide to use 32-bit arithmetic. You have to tell that to it:

> >      n:=longint(h)*3600+m*60+s;

> Thank you, too.

> >Alternatively you could just define h as a longint. The m and s do
not
> >matter as once the type switches to longint the rest is longint and
> >m*60 cannot overflow.

> Sorry, i tried it, and it wont work on my side.

> If i do

>   n:=longint(h)*3600+m*3600+s

m * 3600 ???
're you sure ???
this of course will cause trouble...

Quote:

> TP wont do it. I have to explicitly announce a LongInt-result each
> time ( longint(m)*3600 ) or define the variables as LongInts right
> away.

[snip]

jochen

Sat, 19 Jul 2003 04:58:25 GMT

 Page 1 of 3 [ 30 post ] Go to page: [1] [2] [3]

Relevant Pages

Powered by phpBB® Forum Software