Board index » off-topic » bug in calculation of "longint shr 31"?

bug in calculation of "longint shr 31"?


2004-11-19 02:26:15 AM
off-topic14
Hi,
I im using the following statements in my TP 6.0 Program:
var i: longInt;
begin
i := $7fffffff;
i := i shr 31;
end.
As result i should be 0. But the program results in i being 65534.
i := $7fffffff shr 31,
calculated by the compiler, gives the expected result of 0.
I had been getting crazy debugging my program for hours till I found this error.
Can anyone tell me: Is this a bug or am I doing something wrong?
Is shr defined for 32-bit values in TP 6.0? Or is there some memory buzzing happening within the registers?
Thanks a lot,
Johannes.
 
 

Re:bug in calculation of "longint shr 31"?

"Johannes Ponader" < XXXX@XXXXX.COM >wrote in
Quote
Can anyone tell me: Is this a bug or am I doing something wrong?
Is shr defined for 32-bit values in TP 6.0? Or is there some memory
buzzing happening within the registers?
Looks like the lower 16 bits are being sign extended when the shift value
is more than 16. 16 gives $00007FFF as expected, but 17 gives $0000BFFF,
instead of $00003FFF.
Try this.
Var I : LongInt;
J : Byte;
Begin
I := $7FFFFFFF;
J := 31;
If J>16 then
Begin
I := I div $10000;
I := I shr (J - 16)
End
Else
I := I shr J;
End.
 

Re:bug in calculation of "longint shr 31"?

In article <419cf757$ XXXX@XXXXX.COM >, "Johannes Ponader"
< XXXX@XXXXX.COM >wrote:
Quote
I im using the following statements in my TP 6.0 Program:

var i: longInt;

begin
i := $7fffffff;
i := i shr 31;
end.

As result i should be 0. But the program results in i being 65534.
I cannot reproduce this.
I added these lines
if i<>0 then writeln('not zero');
writeln(i);
the output is:
0
Quote
Can anyone tell me: Is this a bug or am I doing something wrong?
Is that really all you have in your test program, or are there other lines
you have omitted.
 

{smallsort}

Re:bug in calculation of "longint shr 31"?

Repost from the 18th:
"Johannes Ponader" < XXXX@XXXXX.COM >wrote in
Quote
Can anyone tell me: Is this a bug or am I doing something wrong?
Is shr defined for 32-bit values in TP 6.0? Or is there some memory
buzzing happening within the registers?
Looks like the lower 16 bits are being sign extended when the shift value
is more than 16. 16 gives $00007FFF as expected, but 17 gives $0000BFFF,
instead of $00003FFF.
Try this.
Var I : LongInt;
J : Byte;
Begin
I := $7FFFFFFF;
J := 31;
If J>16 then
Begin
I := I div $10000;
I := I shr (J - 16)
End
Else
I := I shr J;
End.
 

Re:bug in calculation of "longint shr 31"?

Iain Macmillan wrote:
Quote

In article <419cf757$ XXXX@XXXXX.COM >, "Johannes Ponader"
< XXXX@XXXXX.COM >wrote:

>I im using the following statements in my TP 6.0 Program:
>
>var i: longInt;
>
>begin
>i := $7fffffff;
>i := i shr 31;
>end.
>
>As result i should be 0. But the program results in i being 65534.

I cannot reproduce this.
I added these lines

if i<>0 then writeln('not zero');
writeln(i);

the output is:
0

>Can anyone tell me: Is this a bug or am I doing something wrong?
Is that really all you have in your test program, or are there other lines
you have omitted.
I just tried it in BP70 and the result is as stated 65534. What
version did you try it in?
Cheers Hanford
 

Re:bug in calculation of "longint shr 31"?

On 18 Nov 2004 11:26:15 -0700, "Johannes Ponader"
< XXXX@XXXXX.COM >wrote:
Quote

Hi,

I im using the following statements in my TP 6.0 Program:

var i: longInt;

begin
i := $7fffffff;
i := i shr 31;
end.

As result i should be 0. But the program results in i being 65534.

i := $7fffffff shr 31,

calculated by the compiler, gives the expected result of 0.

I had been getting crazy debugging my program for hours till I found this error.

Can anyone tell me: Is this a bug or am I doing something wrong?
Is shr defined for 32-bit values in TP 6.0? Or is there some memory buzzing happening within the registers?
My memory is that there is a bug when you try to shift by more
than 8 bits at once.
 

Re:bug in calculation of "longint shr 31"?

"Hanford Carr @lmcinvestments.com>" <"hwcarr<no spam>wrote in message
Quote
Iain Macmillan wrote:
>
>In article <419cf757$ XXXX@XXXXX.COM >, "Johannes Ponader"
>< XXXX@XXXXX.COM >wrote:
>
>>I im using the following statements in my TP 6.0 Program:
>>
>>var i: longInt;
>>
>>begin
>>i := $7fffffff;
>>i := i shr 31;
>>end.
>>
>>As result i should be 0. But the program results in i being 65534.
>
>I cannot reproduce this.
>I added these lines
>
>if i<>0 then writeln('not zero');
>writeln(i);
>
>the output is:
>0
>
>>Can anyone tell me: Is this a bug or am I doing something wrong?
>Is that really all you have in your test program, or are there other
lines
>you have omitted.

I just tried it in BP70 and the result is as stated 65534. What
version did you try it in?
IIRC, this is a known bug in 7.00 when a 386+ is detected (Test8086>= 2).
BP7.00 users can prevent this bug with:
if Test8086>1 then
Test8086 := 1;
at the start of their program.
The bug was fixed in the silent TP/BP 7.01 release.
I don't know that it's a known TP6 bug though.
--
Jay
Author of Graphic Vision
homepage.ntlworld.com/gvision/
 

Re:bug in calculation of "longint shr 31"?

"Hanford Carr @lmcinvestments.com>" <"hwcarr<no spam>schreef in bericht
Quote
Iain Macmillan wrote:
>
>In article <419cf757$ XXXX@XXXXX.COM >, "Johannes Ponader"
>< XXXX@XXXXX.COM >wrote:
>
>>I im using the following statements in my TP 6.0 Program:
>>
>>var i: longInt;
>>
>>begin
>>i := $7fffffff;
>>i := i shr 31;
>>end.
>>
>>As result i should be 0. But the program results in i being 65534.
>
>I cannot reproduce this.
>I added these lines
>
>if i<>0 then writeln('not zero');
>writeln(i);
>
>the output is:
>0
>
>>Can anyone tell me: Is this a bug or am I doing something wrong?
>Is that really all you have in your test program, or are there other
lines
>you have omitted.

I just tried it in BP70 and the result is as stated 65534. What
version did you try it in?

Like Ian says, I can't reproduce the error either in real or protected
mode.
My version is BP 7.01
 

Re:bug in calculation of "longint shr 31"?

Quote
>I just tried it in BP70 and the result is as stated 65534. What
>version did you try it in?

Like Ian says, I can't reproduce the error either in real or protected
mode.
My version is BP 7.01

I'm quite shure now it is a bug in Version 7.0, fixed in V 7.01.
It had cost me hours of debugging, but now I finally got it (i had been repairing an old dblspace-compressed disk which i couldn't access for 8 years now. but now i got it.)
Thanks to all who replied to my question! (and thanks to the author of the "CVF Hacker's Guide" :-)
JonasP.
 

Re:bug in calculation of "longint shr 31"?

JRS: In article <419cf757$ XXXX@XXXXX.COM >, dated Thu, 18 Nov
2004 11:26:15, seen in news:borland.public.turbopascal, Johannes Ponader
< XXXX@XXXXX.COM >posted :
Quote

Can anyone tell me: Is this a bug or am I doing something wrong?
Be aware that bugs lists were produced for (at least) TP6, BP7; they
are referenced in the c.l.p.b mFAQ, which is regularly posted in
--
?John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v4.00 MIME. ?
<URL:www.merlyn.demon.co.uk/>TP/BP/Delphi/&c., FAQqy topics & links;
<URL:www.merlyn.demon.co.uk/clpb-faq.txt>RAH Prins : c.l.p.b mFAQ;
<URL:garbo.uwasa.fi/pc/link/tsfaqp.zip>Timo Salmi's Turbo Pascal FAQ.
 

Re:bug in calculation of "longint shr 31"?

In article < XXXX@XXXXX.COM >, "Jeffrey A.
Wormsley" < XXXX@XXXXX.COM >wrote:
Quote
Looks like the lower 16 bits are being sign extended when the shift value
is more than 16. 16 gives $00007FFF as expected, but 17 gives $0000BFFF,
instead of $00003FFF.
Again, I get 32767 after shr 16
16383 17
- both correct.
TP 6.0
- what can explain the difference between our results?
- hardware ???
 

Re:bug in calculation of "longint shr 31"?

On 18 Nov 2004 11:26:15 -0700, "Johannes Ponader"
< XXXX@XXXXX.COM >wrote:
Quote

Hi,

I im using the following statements in my TP 6.0 Program:

var i: longInt;

begin
i := $7fffffff;
i := i shr 31;
end.

As result i should be 0. But the program results in i being 65534.

i := $7fffffff shr 31,

calculated by the compiler, gives the expected result of 0.

I had been getting crazy debugging my program for hours till I found this error.

Can anyone tell me: Is this a bug or am I doing something wrong?
Is shr defined for 32-bit values in TP 6.0? Or is there some memory buzzing happening within the registers?

It is a known BP 7.00 bug, not found in TP 6.0 or BP 7.01 (Bug 29 in
Duncan Murdoch's 700.lst:
"29. On a 386, a longint shift of 16 bits or more is unreliable. (A
fix is available in NEWSHR.FIX.)"
Strictly speaking it is a BP7.00 386 bug, as the slighty modified code
snipped shows:
program bug29;
var
i: longInt;
begin
for test8086:=2 downto 0 do begin
i := $7fffffff;
i := i shr 31;
writeln(test8086:5, ' ', i);
end;
end.
E:\TMP>bpc BUG29.PAS
Borland Pascal Version 7.0 Copyright (c) 1983,92 Borland
International
BUG29.PAS(11)
11 lines, 2784 bytes code, 674 bytes data.
E:\TMP>BUG29.EXE
2 65534
1 0
0 0
The variable test8086 is set by the system initialization code and
selects 386 code for some RTL routines (see online help), the bug is
located in LONG.ASM.
Wolfgang
--
In order to e-mail me a reply to this message, you will have
to remove PLEASE.REMOVE from the address shown in the header
or get it from home.netsurf.de/wolfgang.ehrhardt
(Free AES, CRC, Hash, and HMAC source for Pascal/Delphi)
 

Re:bug in calculation of "longint shr 31"?

"Wolfgang Ehrhardt" < XXXX@XXXXX.COM >
wrote in message news: XXXX@XXXXX.COM ...
Quote
On 18 Nov 2004 11:26:15 -0700, "Johannes Ponader"
< XXXX@XXXXX.COM >wrote:

>I im using the following statements in my TP 6.0 Program:
>
>var i: longInt;
>
>begin
>i := $7fffffff;
>i := i shr 31;
>end.
>
>As result i should be 0. But the program results in i being 65534.
>
>i := $7fffffff shr 31,
>
>calculated by the compiler, gives the expected result of 0.
>
>I had been getting crazy debugging my program for hours till I found
>this error.
>
>Can anyone tell me: Is this a bug or am I doing something wrong?
>Is shr defined for 32-bit values in TP 6.0? Or is there some memory
>buzzing happening within the registers?

It is a known BP 7.00 bug, not found in TP 6.0 or BP 7.01 (Bug 29 in
Duncan Murdoch's 700.lst:
"29. On a 386, a longint shift of 16 bits or more is unreliable. (A
fix is available in NEWSHR.FIX.)"

Strictly speaking it is a BP7.00 386 bug, as the slighty modified code
snipped shows:

program bug29;

var
i: longInt;

begin
for test8086:=2 downto 0 do begin
i := $7fffffff;
i := i shr 31;
writeln(test8086:5, ' ', i);
end;
end.

E:\TMP>bpc BUG29.PAS
Borland Pascal Version 7.0 Copyright (c) 1983,92 Borland
International
BUG29.PAS(11)
11 lines, 2784 bytes code, 674 bytes data.

E:\TMP>BUG29.EXE
2 65534
1 0
0 0

The variable test8086 is set by the system initialization code and
selects 386 code for some RTL routines (see online help), the bug is
located in LONG.ASM.
Get BPL70N16.ZIP (Norbert Juffa's based on BP 7.00, but without the
bugs) or my BLP70V20.ZIP (need>=386) and the problem will be gone and
you're programs will also be a bit smaller and faster.
Robert
--
Robert AH Prins
prino at onetel dot com
 

Re:bug in calculation of "longint shr 31"?

Quote
Get BPL70N16.ZIP (Norbert Juffa's based on BP 7.00, but without the
bugs) or my BLP70V20.ZIP (need>=386) and the problem will be gone and
you're programs will also be a bit smaller and faster.
Since longint math often is used in time critical parts (inner loops
and so on), it might be a good idea to use inline macros. That way you
reduce a lot of the overhead that a procedure or function call gives.
I use the unit MACRO.PAS (listed below) for most of my time critical
code. On modern, fast computers the difference isn't that big, but on
slower, old ones it can be quite significant.
unit Macro;
{$g+}
{ -=:*:=- macros -=:*:=- }
{ various inline macros collected/rewritten/written by
Björn Felten @ FidoNet 2:203/208 }
{ -- Public Domain -- }
interface
function readKey:char;inline
($B4/$07/ { mov ah,7 }
$CD/$21); { int $21 }
function xreadKey:char;inline
($B4/$10/ { mov ah,10h }
$CD/$16); { int 16h }
function keyPressed:boolean;inline
($B4/$0B/ { mov ah,$B }
$CD/$21/ { int $21 }
$24/$FE); { and al,$FE }
{ fast sqrt -- returns int part in hi word and fract part in low}
function iSqrt(x:longint):longint;
inline
($66/$33/$c0 { xor eax,eax}
/$66/$33/$d2 { xor edx,edx}
/$66/$5f { pop edi}
/$b9/$20/$00 { mov cx,32}
{@L:}
/$66/$d1/$e7 { shl edi,1}
/$66/$d1/$d2 { rcl edx,1}
/$66/$d1/$e7 { shl edi,1}
/$66/$d1/$d2 { rcl edx,1}
/$66/$d1/$e0 { shl eax,1}
/$66/$8b/$d8 { mov ebx,eax}
/$66/$d1/$e3 { shl ebx,1}
/$66/$43 { inc ebx}
/$66/$3b/$d3 { cmp edx,ebx}
/$7c/$05 { jl @S}
/$66/$2b/$d3 { sub edx,ebx}
/$66/$40 { inc eax}
{@S:}
/$e2/$dd { loop @L}
/$66/$8b/$d0 { mov edx,eax}
/$66/$c1/$ea/$10); { shr edx,16}
function swapLong(l:longint):longint;
inline
($5a { pop dx }
/$58); { pop ax }
function swapWords(x,y:word):longint;
inline
($58 { pop ax }
/$5a); { pop dx }
function Mul32(a,b:longint):longint;
inline($fa/$66/$59/$66/$58/$66/$f7/$e9/$66/$0f/$a4/$c2/$10/$fb);
function Div32(a,b:longint):longint;
inline($fa/$66/$59/$66/$58/$66/$99/$66/$f7/$f9/$66/$0f/$a4/$c2/$10/$fb);
function Shl32(a:longint;b:word):longint;
inline($fa/$59/$66/$58/$66/$d3/$e0/$66/$0f/$a4/$c2/$10/$fb);
function Shr32(a:longint;b:word):longint;
inline($fa/$59/$66/$58/$66/$d3/$e8/$66/$0f/$a4/$c2/$10/$fb);
function Sar32(a:longint;b:word):longint;
inline($fa/$59/$66/$58/$66/$d3/$f8/$66/$0f/$a4/$c2/$10/$fb);
function Rol32(a:longint;b:word):longint;
inline($fa/$59/$66/$58/$66/$d3/$c0/$66/$0f/$a4/$c2/$10/$fb);
function Ror32(a:longint;b:word):longint;
inline($fa/$59/$66/$58/$66/$d3/$c8/$66/$0f/$a4/$c2/$10/$fb);
function Long2Hex(L: longint): string;
inline(
$66/$5b { pop ebx ; ebx = L }
/$16 { push ss }
/$07 { pop es ; es = ss }
/$b8/$08/$00 { mov ax,8 }
/$aa { stosb }
/$89/$c1 { mov cx,ax }
{@@loo: }
/$66/$c1/$c3/$04 { rol ebx,4 }
/$88/$d8 { mov al,bl }
/$24/$0f { and al,15 }
/$04/$90 { add al,90h }
/$27 { daa }
/$14/$40 { adc al,40h }
/$27 { daa }
/$0c/$20 { or al,20h }
/$aa { stosb }
/$e2/$ed); { loop @loo }
function Word2Hex(L: word): string;
inline(
$5b { pop bx ; bx = L }
/$16 { push ss }
/$07 { pop es ; es = ss }
/$b8/$04/$00 { mov ax,4 }
/$aa { stosb }
/$89/$c1 { mov cx,ax }
{@@loo: }
/$c1/$c3/$04 { rol bx,4 }
/$88/$d8 { mov al,bl }
/$24/$0f { and al,15 }
/$04/$90 { add al,90h }
/$27 { daa }
/$14/$40 { adc al,40h }
/$27 { daa }
/$0c/$20 { or al,20h }
/$aa { stosb }
/$e2/$ee); { loop @loo }
implementation
end.
--
FidoNet in your news reader: news://felten.dyndns.org
For full access, register at: felten.dyndns.org/join.html
 

Re:bug in calculation of "longint shr 31"?

In article < XXXX@XXXXX.COM >, Hanford Carr <"hwcarr<no
spam>"@lmcinvestments.com>wrote:
Quote
I just tried it in BP70 and the result is as stated 65534. What
version did you try it in?
TP 6.0
This is what the original question said:
Quote
I im using the following statements in my TP 6.0 Program:
<snip>
Is shr defined for 32-bit values in TP 6.0?
However the post from JonasP - presumably the Original Poster - says
I'm quite shure now it is a bug in Version 7.0, fixed in V 7.01.
That, plus Wolfgang's post lead me to think that the original statement that
the bug occurred in a TP6 prog was a blatant misinformation.
---------
[so, it's another bug in v7. (I never get RTE 200 either - except of course
if I divide by zero)]