Error #215 Arithmetic overflow, where it shouldn′t occur(?)
Author 
Message 
Michael Ros #1 / 30

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 QR... 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 


Osmo Ronkan #2 / 30

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 16bits. It cannot guess that in the particular case it might overflow and therefore decide to use 32bit 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 


Hanford Car #3 / 30

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 > QR... 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 


byates.. #4 / 30

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 > QR... 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 longval in the longint, 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 


Michael Ros #5 / 30

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 longval in the >longint, 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 


Michael Ros #6 / 30

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 


Michael Ros #7 / 30

Error #215 Arithmetic overflow, where it shouldn′t occur(?)
Quote: >Typecast h as longint. TP does normally arithmetic with 16bits. It >cannot guess that in the particular case it might overflow and therefore >decide to use 32bit 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 LongIntresult 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 


Hanford Car #8 / 30

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 


Michael Ros #9 / 30

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 $Qdirective, 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 


Osmo Ronkan #10 / 30

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 16bit compiler. It uses 16bit operations whenever possible. If this then results in an overflow, it results in an overflow. The reason for this is that 16bit operations are much much much faster. However, in case of multiplication the 16bit multiplication results in a 32bit value. A HLL like Pascal expects result to be same type as the operation so it does not use the 16bit 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 


#11 / 30

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

Wed, 18 Jun 1902 08:00:00 GMT 


Osmo Ronkan #12 / 30

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 


#13 / 30

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

Wed, 18 Jun 1902 08:00:00 GMT 


Osmo Ronkan #14 / 30

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 


Joche #15 / 30

Error #215 Arithmetic overflow, where it shouldn′t occur(?)
Quote:
> >Typecast h as longint. TP does normally arithmetic with 16bits. It > >cannot guess that in the particular case it might overflow and therefore > >decide to use 32bit 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 LongIntresult 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] 
