Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > Different behaviour linux vs Win32

Reply
Thread Tools

Different behaviour linux vs Win32

 
 
Dazza T
Guest
Posts: n/a
 
      09-10-2006
I have some code that is meant to take a 32-bit number [0-0xFFFFFFFF] and
round it down to the next exact multiple of a given `step'. It uses the %
modulo operator and assumes we are dealing with unsigned integers (yes, I
know, but read on). If I run it on a Win32 ActiveState system, it always
gives me the answer I expect. But when I run it on a linux system with a
value greater than 0x8000000, it doesn't work.

I think the problem is to do with `signed' vs `unsigned' integers and, OK, I
can live with that. The % operator advertises different behaviour with
negative numbers.

*BUT* if I put a debugging print statement in the code, it starts working
correctly again on the Linux system. Such behaviour really worries me.

1) What's wrong with the code below and how should it be changed so it will
work with all 32-bit unsigned integers [0-0xFFFFFFFF] on any operating
system?

2) Why does the intervening print statement change things?

===(code 1)===
#!/usr/local/bin/perl
use strict
my ($base, $step);
$step = 0x7f79;
$base = 0xE195ED24;
printf "BASE =%08X\n", $base;
# Adjust it to be an exact multiple of the step so base mod step == 0
printf "ADJST=%08X\n", ($base % $step);
$base -= ($base % $step);
printf "EXACT=%08X\n", $base;
# check
printf "CHECK=%08X\n", ($base % $step);
===(end code)===

RESULTS:-

1. Windows 2000 Pro; perl, v5.6.1 built for MSWin32-x86-multi-thread
BASE =E195ED24
ADJST=000054E3
EXACT=E1959841
CHECK=00000000 (expecting zero)

2. perl, v5.6.0 built for i386-linux
BASE =E195ED24
ADJST=00003711
EXACT=E195B613
CHECK=00001DD2 (wrong!)

OK, so the original number is interpreted here as a negative number and % is
advertised
as treating negative numbers differently from positive ones.

BUT if we add a debugging print statement to the code, it works as we
expect!

===(code 2)===
#!/usr/local/bin/perl
use strict
my ($base, $step);
$step = 0x7f79;
$base = 0xE195ED24;
printf "BASE =%08X\n", $base;
# PUT A PRINT STATEMENT INBETWEEN...
print "$base $step\n", ($base / $step), "\n", ($base % $step), "\n";
# Adjust it to be an exact multiple of the step so base mod step == 0
printf "ADJST=%08X\n", ($base % $step);
$base -= ($base % $step);
printf "EXACT=%08X\n", $base;
# check
printf "CHECK=%08X\n", ($base % $step);
===(end code)===

3. perl, v5.6.0 built for i386-linux
BASE =E195ED24
3784699172 32633
115977.665921
21731
ADJST=000054E3
EXACT=E1959841
CHECK=00000000

Why is this?


 
Reply With Quote
 
 
 
 
Peter J. Holzer
Guest
Posts: n/a
 
      09-10-2006
On 2006-09-10 14:22, Dazza T <(E-Mail Removed)> wrote:
> I have some code that is meant to take a 32-bit number [0-0xFFFFFFFF] and
> round it down to the next exact multiple of a given `step'. It uses the %
> modulo operator and assumes we are dealing with unsigned integers (yes, I
> know, but read on). If I run it on a Win32 ActiveState system, it always
> gives me the answer I expect. But when I run it on a linux system with a
> value greater than 0x8000000, it doesn't work.
>
> I think the problem is to do with `signed' vs `unsigned' integers and, OK, I
> can live with that. The % operator advertises different behaviour with
> negative numbers.
>
>===(code 1)===
> #!/usr/local/bin/perl
> use strict
> my ($base, $step);
> $step = 0x7f79;
> $base = 0xE195ED24;
> printf "BASE =%08X\n", $base;
> # Adjust it to be an exact multiple of the step so base mod step == 0
> printf "ADJST=%08X\n", ($base % $step);
> $base -= ($base % $step);
> printf "EXACT=%08X\n", $base;
> # check
> printf "CHECK=%08X\n", ($base % $step);
>===(end code)===
>
> RESULTS:-
>
> 1. Windows 2000 Pro; perl, v5.6.1 built for MSWin32-x86-multi-thread
> BASE =E195ED24
> ADJST=000054E3
> EXACT=E1959841
> CHECK=00000000 (expecting zero)
>
> 2. perl, v5.6.0 built for i386-linux
> BASE =E195ED24
> ADJST=00003711
> EXACT=E195B613
> CHECK=00001DD2 (wrong!)


perl, v5.6.1 built for i386-linux
BASE =E195ED24
ADJST=000054E3
EXACT=E1959841
CHECK=00000000

> 1) What's wrong with the code below and how should it be changed so it will
> work with all 32-bit unsigned integers [0-0xFFFFFFFF] on any operating
> system?


The same result as with perl 5.6.1 under Windows. So it doesn't seem to
be a difference between Linux and Windows, but between perl 5.6.0 and
5.6.1. Probably a bug in 5.6.0 which was corrected in 5.6.1.

BTW, these perl versions are 6 years old. Do yourself a favour and
upgrade to a current version of perl (and to a current version of Linux,
too).

> *BUT* if I put a debugging print statement in the code, it starts working
> correctly again on the Linux system. Such behaviour really worries me.
>
> 2) Why does the intervening print statement change things?
>
>===(code 2)===
> #!/usr/local/bin/perl
> use strict
> my ($base, $step);
> $step = 0x7f79;
> $base = 0xE195ED24;
> printf "BASE =%08X\n", $base;
> # PUT A PRINT STATEMENT INBETWEEN...
> print "$base $step\n", ($base / $step), "\n", ($base % $step), "\n";
> # Adjust it to be an exact multiple of the step so base mod step == 0
> printf "ADJST=%08X\n", ($base % $step);
> $base -= ($base % $step);
> printf "EXACT=%08X\n", $base;
> # check
> printf "CHECK=%08X\n", ($base % $step);
>===(end code)===
>
> 3. perl, v5.6.0 built for i386-linux
> BASE =E195ED24
> 3784699172 32633
> 115977.665921
> 21731
> ADJST=000054E3
> EXACT=E1959841
> CHECK=00000000
>
> Why is this?


Perl scalars can be strings, floating point numbers, integral numbers
and a few other things. Depending on how to use them they can be one or
several of these types at once.

If you use Devel:eek:ump to look at $base, you can see that the
print statement changes $base:

| #!/usr/local/bin/perl
| use Devel:eek;
| use strict;
| my ($base, $step);
| $step = 0x7f79;
| $base = 0xE195ED24;
| printf "BASE =%08X\n", $base;
| Dump ($base);
| print "$base $step\n", ($base / $step), "\n", ($base % $step), "\n";
| Dump ($base);
| # Adjust it to be an exact multiple of the step so base mod step == 0
| printf "ADJST=%08X\n", ($base % $step);
| $base -= ($base % $step);
| printf "EXACT=%08X\n", $base;
| # check
| printf "CHECK=%08X\n", ($base % $step);


| BASE =E195ED24
| SV = IV(0x80f6310) at 0x80f59e8
| REFCNT = 1
| FLAGS = (PADBUSY,PADMY,IOK,pIOK,IsUV)
| UV = 3784699172

Here $base is an unsigned integer (UV).

| 3784699172 32633
| 115977.665921
| 21731
| SV = PVNV(0x80eb470) at 0x80f59e8
| REFCNT = 1
| FLAGS = (PADBUSY,PADMY,IOK,NOK,POK,pIOK,pNOK,pPOK,IsUV)
| UV = 3784699172
| NV = 3784699172
| PV = 0x80ef570 "3784699172"\0
| CUR = 10
| LEN = 11

But now $base is also a floating point number (NV) and a string (PV).
This is because you used it in a floating point division and a string
interpolation. My guess is that perl takes the NV in a % operation if
there is one, so it gets the correct result. If there is no NV, it takes
the UV, but unsigned % seems to be buggy in perl 5.6.0 (it does a signed
% instead).

| ADJST=000054E3
| EXACT=E1959841
| CHECK=00000000

hp


--
_ | Peter J. Holzer | > Wieso sollte man etwas erfinden was nicht
|_|_) | Sysadmin WSR | > ist?
| | | http://www.velocityreviews.com/forums/(E-Mail Removed) | Was sonst wäre der Sinn des Erfindens?
__/ | http://www.hjp.at/ | -- P. Einstein u. V. Gringmuth in desd
 
Reply With Quote
 
 
 
 
anno4000@radom.zrz.tu-berlin.de
Guest
Posts: n/a
 
      09-10-2006
Dazza T <(E-Mail Removed)> wrote in comp.lang.perl.misc:

> I have some code that is meant to take a 32-bit number [0-0xFFFFFFFF] and
> round it down to the next exact multiple of a given `step'. It uses the %
> modulo operator and assumes we are dealing with unsigned integers (yes, I
> know, but read on). If I run it on a Win32 ActiveState system, it always
> gives me the answer I expect. But when I run it on a linux system with a
> value greater than 0x8000000, it doesn't work.


[snippage]

> 1. Windows 2000 Pro; perl, v5.6.1 built for MSWin32-x86-multi-thread


> 2. perl, v5.6.0 built for i386-linux


> 3. perl, v5.6.0 built for i386-linux


> Why is this?


I don't know. You may have found a bug in 5.6.0 or 5.6.1.

These are ancient versions of Perl. Upgrade, and if the error persists,
file a bug report. I can't reproduce it with 5.8.7 or 5.9.4.

Anno
 
Reply With Quote
 
Dazza T
Guest
Posts: n/a
 
      09-10-2006
"Peter J. Holzer" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> On 2006-09-10 14:22, Dazza T <(E-Mail Removed)> wrote:
> > I have some code that is meant to take a 32-bit number [0-0xFFFFFFFF]

and
> > round it down to the next exact multiple of a given `step'. It uses the

%
> > modulo operator and assumes we are dealing with unsigned integers (yes,

I
> > know, but read on). If I run it on a Win32 ActiveState system, it always
> > gives me the answer I expect. But when I run it on a linux system with a
> > value greater than 0x8000000, it doesn't work.
> >
> > I think the problem is to do with `signed' vs `unsigned' integers and,

OK, I
> > can live with that. The % operator advertises different behaviour with
> > negative numbers.
> >

[snipped]
> The same result as with perl 5.6.1 under Windows. So it doesn't seem to
> be a difference between Linux and Windows, but between perl 5.6.0 and
> 5.6.1. Probably a bug in 5.6.0 which was corrected in 5.6.1.
>
> BTW, these perl versions are 6 years old. Do yourself a favour and
> upgrade to a current version of perl (and to a current version of Linux,
> too).
>
> > *BUT* if I put a debugging print statement in the code, it starts

working
> > correctly again on the Linux system. Such behaviour really worries me.
> >
> > 2) Why does the intervening print statement change things?
> >

[snipped]
>
> Perl scalars can be strings, floating point numbers, integral numbers
> and a few other things. Depending on how to use them they can be one or
> several of these types at once.
>
> If you use Devel:eek:ump to look at $base, you can see that the
> print statement changes $base:
>

[snipped]
>
> But now $base is also a floating point number (NV) and a string (PV).
> This is because you used it in a floating point division and a string
> interpolation. My guess is that perl takes the NV in a % operation if
> there is one, so it gets the correct result. If there is no NV, it takes
> the UV, but unsigned % seems to be buggy in perl 5.6.0 (it does a signed
> % instead).
>

[snipped]
>
> hp
>
>
> --
> _ | Peter J. Holzer | > Wieso sollte man etwas erfinden was nicht
> |_|_) | Sysadmin WSR | > ist?
> | | | (E-Mail Removed) | Was sonst wre der Sinn des Erfindens?
> __/ | http://www.hjp.at/ | -- P. Einstein u. V. Gringmuth in desd


BTW, these perl versions are 6 years old. Do yourself a favour and
upgrade to a current version of perl (and to a current version of Linux,
too).

-- Point taken and I'd love to upgrade but my web site provider gives me
what he gives. That's why I keep the 5.6 version on my Win32 system.


But now $base is also a floating point number (NV) and a string (PV).
This is because you used it in a floating point division and a string
interpolation. My guess is that perl takes the NV in a % operation if
there is one, so it gets the correct result. If there is no NV, it takes
the UV, but unsigned % seems to be buggy in perl 5.6.0 (it does a signed
% instead).

-- This would seem to be consistent. Thanks for the hints about
Devel:eek:ump. I can see a good workaround for this now.

Dazza.



 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Different behaviour in different struct declaration types __PaTeR C Programming 7 01-01-2009 12:13 AM
Win32::OLE different connections methods produce different results HmJ Perl Misc 0 03-28-2008 02:46 PM
Different behaviour reading static field Windows vs Linux colibri Java 7 09-23-2007 09:33 PM
debugger behaviour different to execution behaviour Andy Chambers Java 1 05-14-2007 09:51 AM
different behaviour of JPopup menu on windows and linux CharlesRiver Java 0 04-03-2006 02:03 AM



Advertisments