Connecting Tech Pros Worldwide Forums | Help | Site Map

& behaves differently

fritz-bayer@web.de
Guest
 
Posts: n/a
#1: Mar 3 '06
Hi,

why does the php expression

$result = 5543039447 & 2147483648;

when executed evaluate to 0, whereas the perl expression

$same = 5543039447 & 2147483648 ;

evaluate to 2147483648 ???

Fritz


d
Guest
 
Posts: n/a
#2: Mar 3 '06

re: & behaves differently


<fritz-bayer@web.de> wrote in message
news:1141407160.003705.72180@i40g2000cwc.googlegro ups.com...[color=blue]
> Hi,
>
> why does the php expression
>
> $result = 5543039447 & 2147483648;
>
> when executed evaluate to 0, whereas the perl expression
>
> $same = 5543039447 & 2147483648 ;
>
> evaluate to 2147483648 ???[/color]

Because perl is screwed?

5543039447 = 101001010011001000001000111010111

and

2147483648 = 010000000000000000000000000000000

As you can see, if you and both of those, you get zero. It seems PHP is
right on this one.
[color=blue]
> Fritz
>[/color]

dave


fritz-bayer@web.de
Guest
 
Posts: n/a
#3: Mar 3 '06

re: & behaves differently


Are you serious about this? I mean you are right that it should be
zero, but could it be, that I have to use a different expression? Or
use a function instead of using the & ? Have you tried it yourself on
your machine? Do you get the same result?

Jerry Stuckle
Guest
 
Posts: n/a
#4: Mar 3 '06

re: & behaves differently


fritz-bayer@web.de wrote:[color=blue]
> Hi,
>
> why does the php expression
>
> $result = 5543039447 & 2147483648;
>
> when executed evaluate to 0, whereas the perl expression
>
> $same = 5543039447 & 2147483648 ;
>
> evaluate to 2147483648 ???
>
> Fritz
>[/color]

Because Perl is using 64 bit integers and PHP is using 32 bit integers.

2147483648 is not a valid value in 32 bit arithmetic. The largest value
you can have is 2147483647.

--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
jstucklex@attglobal.net
==================
d
Guest
 
Posts: n/a
#5: Mar 3 '06

re: & behaves differently


<fritz-bayer@web.de> wrote in message
news:1141409437.320652.250950@t39g2000cwt.googlegr oups.com...[color=blue]
> Are you serious about this? I mean you are right that it should be
> zero, but could it be, that I have to use a different expression? Or
> use a function instead of using the & ? Have you tried it yourself on
> your machine? Do you get the same result?[/color]

Those numbers are straight from a test I did on my machine. If you look at
those numbers expressed in binary, you can see that a bitwise and will
return 0, as there is only one bit set to 1 in the second number, and the
corresponding bit in the first number is a 0, hence the result of the
bitwise and is 0.

If perl gives you a different number, then perl either wasn't doing a
bitwise and (though the perl docs say otherwise), or you were using
different numbers...

cheers!

dave


d
Guest
 
Posts: n/a
#6: Mar 3 '06

re: & behaves differently


"Jerry Stuckle" <jstucklex@attglobal.net> wrote in message
news:P4qdnZ1ghuZKFJXZRVn-qw@comcast.com...[color=blue]
> fritz-bayer@web.de wrote:[color=green]
>> Hi,
>>
>> why does the php expression
>>
>> $result = 5543039447 & 2147483648;
>>
>> when executed evaluate to 0, whereas the perl expression
>>
>> $same = 5543039447 & 2147483648 ;
>>
>> evaluate to 2147483648 ???
>>
>> Fritz
>>[/color]
>
> Because Perl is using 64 bit integers and PHP is using 32 bit integers.
>
> 2147483648 is not a valid value in 32 bit arithmetic. The largest value
> you can have is 2147483647.[/color]

PHP interprets ints over 32 bits as floats, so they are valid.

"If you specify a number beyond the bounds of the integer type, it will be
interpreted as a float instead. Also, if you perform an operation that
results in a number beyond the bounds of the integer type, a float will be
returned instead."
[color=blue]
> --
> ==================
> Remove the "x" from my email address
> Jerry Stuckle
> JDS Computer Training Corp.
> jstucklex@attglobal.net
> ==================[/color]


fritz-bayer@web.de
Guest
 
Posts: n/a
#7: Mar 3 '06

re: & behaves differently


I'm porting some code from php to pearl. Do you a workaournd? I mean
how could I get this working under perl?

d
Guest
 
Posts: n/a
#8: Mar 3 '06

re: & behaves differently


<fritz-bayer@web.de> wrote in message
news:1141418050.683875.211800@t39g2000cwt.googlegr oups.com...[color=blue]
> I'm porting some code from php to pearl. Do you a workaournd? I mean
> how could I get this working under perl?[/color]

perl performs a bitwise and with the & operator, the same as php. The two
numbers you gave will always return 0, so I don't know what the original
code was doing, but it doesn't look like it was performing a bitwise and...


Jerry Stuckle
Guest
 
Posts: n/a
#9: Mar 3 '06

re: & behaves differently


d wrote:[color=blue]
> "Jerry Stuckle" <jstucklex@attglobal.net> wrote in message
> news:P4qdnZ1ghuZKFJXZRVn-qw@comcast.com...
>[color=green]
>>fritz-bayer@web.de wrote:
>>[color=darkred]
>>>Hi,
>>>
>>>why does the php expression
>>>
>>>$result = 5543039447 & 2147483648;
>>>
>>>when executed evaluate to 0, whereas the perl expression
>>>
>>>$same = 5543039447 & 2147483648 ;
>>>
>>>evaluate to 2147483648 ???
>>>
>>>Fritz
>>>[/color]
>>
>>Because Perl is using 64 bit integers and PHP is using 32 bit integers.
>>
>>2147483648 is not a valid value in 32 bit arithmetic. The largest value
>>you can have is 2147483647.[/color]
>
>
> PHP interprets ints over 32 bits as floats, so they are valid.
>
> "If you specify a number beyond the bounds of the integer type, it will be
> interpreted as a float instead. Also, if you perform an operation that
> results in a number beyond the bounds of the integer type, a float will be
> returned instead."
>
>[color=green]
>>--
>>==================
>>Remove the "x" from my email address
>>Jerry Stuckle
>>JDS Computer Training Corp.
>>jstucklex@attglobal.net
>>==================[/color]
>
>
>[/color]

In most cases, yes. However, you cannot perform bit operations on a
float. It must be an integer type.

So the value is converted back to an integer, and since it's outside the
bounds of a 32 bit integer the result is to strip off the high order bits.

The result is zero.

Sometimes a little knowledge is worse than no knowledge at all.


--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
jstucklex@attglobal.net
==================
Jerry Stuckle
Guest
 
Posts: n/a
#10: Mar 3 '06

re: & behaves differently


fritz-bayer@web.de wrote:[color=blue]
> I'm porting some code from php to pearl. Do you a workaournd? I mean
> how could I get this working under perl?
>[/color]

Fritz,

If the Perl (not Pearl) code is performing 32 bit operations, you should
have no problems. If it's performing 64 bit operations, and it with
0x7fffffff (the high order bit is a sign bit).

--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
jstucklex@attglobal.net
==================
d
Guest
 
Posts: n/a
#11: Mar 3 '06

re: & behaves differently


"Jerry Stuckle" <jstucklex@attglobal.net> wrote in message
news:6vCdnYaBloS7MZXZnZ2dnUVZ_vidnZ2d@comcast.com. ..[color=blue]
>d wrote:[color=green]
>> "Jerry Stuckle" <jstucklex@attglobal.net> wrote in message
>> news:P4qdnZ1ghuZKFJXZRVn-qw@comcast.com...
>>[color=darkred]
>>>fritz-bayer@web.de wrote:
>>>
>>>>Hi,
>>>>
>>>>why does the php expression
>>>>
>>>>$result = 5543039447 & 2147483648;
>>>>
>>>>when executed evaluate to 0, whereas the perl expression
>>>>
>>>>$same = 5543039447 & 2147483648 ;
>>>>
>>>>evaluate to 2147483648 ???
>>>>
>>>>Fritz
>>>>
>>>
>>>Because Perl is using 64 bit integers and PHP is using 32 bit integers.
>>>
>>>2147483648 is not a valid value in 32 bit arithmetic. The largest value
>>>you can have is 2147483647.[/color]
>>
>>
>> PHP interprets ints over 32 bits as floats, so they are valid.
>>
>> "If you specify a number beyond the bounds of the integer type, it will
>> be interpreted as a float instead. Also, if you perform an operation that
>> results in a number beyond the bounds of the integer type, a float will
>> be returned instead."
>>
>>[color=darkred]
>>>--
>>>==================
>>>Remove the "x" from my email address
>>>Jerry Stuckle
>>>JDS Computer Training Corp.
>>>jstucklex@attglobal.net
>>>==================[/color]
>>
>>
>>[/color]
>
> In most cases, yes. However, you cannot perform bit operations on a
> float. It must be an integer type.
>
> So the value is converted back to an integer, and since it's outside the
> bounds of a 32 bit integer the result is to strip off the high order bits.
>
> The result is zero.[/color]

The result is zero regardless of whether that bit is there or not :)
[color=blue]
> Sometimes a little knowledge is worse than no knowledge at all.
>[/color]

Indeed.
[color=blue]
> --
> ==================
> Remove the "x" from my email address
> Jerry Stuckle
> JDS Computer Training Corp.
> jstucklex@attglobal.net
> ==================[/color]


Jerry Stuckle
Guest
 
Posts: n/a
#12: Mar 3 '06

re: & behaves differently


d wrote:[color=blue]
> "Jerry Stuckle" <jstucklex@attglobal.net> wrote in message
> news:6vCdnYaBloS7MZXZnZ2dnUVZ_vidnZ2d@comcast.com. ..
>[color=green]
>>d wrote:
>>[color=darkred]
>>>"Jerry Stuckle" <jstucklex@attglobal.net> wrote in message
>>>news:P4qdnZ1ghuZKFJXZRVn-qw@comcast.com...
>>>
>>>
>>>>fritz-bayer@web.de wrote:
>>>>
>>>>
>>>>>Hi,
>>>>>
>>>>>why does the php expression
>>>>>
>>>>>$result = 5543039447 & 2147483648;
>>>>>
>>>>>when executed evaluate to 0, whereas the perl expression
>>>>>
>>>>>$same = 5543039447 & 2147483648 ;
>>>>>
>>>>>evaluate to 2147483648 ???
>>>>>
>>>>>Fritz
>>>>>
>>>>
>>>>Because Perl is using 64 bit integers and PHP is using 32 bit integers.
>>>>
>>>>2147483648 is not a valid value in 32 bit arithmetic. The largest value
>>>>you can have is 2147483647.
>>>
>>>
>>>PHP interprets ints over 32 bits as floats, so they are valid.
>>>
>>>"If you specify a number beyond the bounds of the integer type, it will
>>>be interpreted as a float instead. Also, if you perform an operation that
>>>results in a number beyond the bounds of the integer type, a float will
>>>be returned instead."
>>>
>>>
>>>
>>>>--
>>>>==================
>>>>Remove the "x" from my email address
>>>>Jerry Stuckle
>>>>JDS Computer Training Corp.
>>>>jstucklex@attglobal.net
>>>>==================
>>>
>>>
>>>[/color]
>>In most cases, yes. However, you cannot perform bit operations on a
>>float. It must be an integer type.
>>
>>So the value is converted back to an integer, and since it's outside the
>>bounds of a 32 bit integer the result is to strip off the high order bits.
>>
>>The result is zero.[/color]
>
>
> The result is zero regardless of whether that bit is there or not :)
>
>[color=green]
>>Sometimes a little knowledge is worse than no knowledge at all.
>>[/color]
>
>
> Indeed.
>
>[color=green]
>>--
>>==================
>>Remove the "x" from my email address
>>Jerry Stuckle
>>JDS Computer Training Corp.
>>jstucklex@attglobal.net
>>==================[/color]
>
>
>[/color]

Actually, 0x80000000 is -2147483647 decimal. So the result is not zero.

--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
jstucklex@attglobal.net
==================
fritz-bayer@web.de
Guest
 
Posts: n/a
#13: Mar 4 '06

re: & behaves differently



Jerry Stuckle wrote:[color=blue]
> d wrote:[color=green]
> > "Jerry Stuckle" <jstucklex@attglobal.net> wrote in message
> > news:6vCdnYaBloS7MZXZnZ2dnUVZ_vidnZ2d@comcast.com. ..
> >[color=darkred]
> >>d wrote:
> >>
> >>>"Jerry Stuckle" <jstucklex@attglobal.net> wrote in message
> >>>news:P4qdnZ1ghuZKFJXZRVn-qw@comcast.com...
> >>>
> >>>
> >>>>fritz-bayer@web.de wrote:
> >>>>
> >>>>
> >>>>>Hi,
> >>>>>
> >>>>>why does the php expression
> >>>>>
> >>>>>$result = 5543039447 & 2147483648;
> >>>>>
> >>>>>when executed evaluate to 0, whereas the perl expression
> >>>>>
> >>>>>$same = 5543039447 & 2147483648 ;
> >>>>>
> >>>>>evaluate to 2147483648 ???
> >>>>>
> >>>>>Fritz
> >>>>>
> >>>>
> >>>>Because Perl is using 64 bit integers and PHP is using 32 bit integers.
> >>>>
> >>>>2147483648 is not a valid value in 32 bit arithmetic. The largest value
> >>>>you can have is 2147483647.
> >>>
> >>>
> >>>PHP interprets ints over 32 bits as floats, so they are valid.
> >>>
> >>>"If you specify a number beyond the bounds of the integer type, it will
> >>>be interpreted as a float instead. Also, if you perform an operation that
> >>>results in a number beyond the bounds of the integer type, a float will
> >>>be returned instead."
> >>>
> >>>
> >>>
> >>>>--
> >>>>==================
> >>>>Remove the "x" from my email address
> >>>>Jerry Stuckle
> >>>>JDS Computer Training Corp.
> >>>>jstucklex@attglobal.net
> >>>>==================
> >>>
> >>>
> >>>
> >>In most cases, yes. However, you cannot perform bit operations on a
> >>float. It must be an integer type.
> >>
> >>So the value is converted back to an integer, and since it's outside the
> >>bounds of a 32 bit integer the result is to strip off the high order bits.
> >>
> >>The result is zero.[/color]
> >
> >
> > The result is zero regardless of whether that bit is there or not :)
> >
> >[color=darkred]
> >>Sometimes a little knowledge is worse than no knowledge at all.
> >>[/color]
> >
> >
> > Indeed.
> >
> >[color=darkred]
> >>--
> >>==================
> >>Remove the "x" from my email address
> >>Jerry Stuckle
> >>JDS Computer Training Corp.
> >>jstucklex@attglobal.net
> >>==================[/color]
> >
> >
> >[/color]
>
> Actually, 0x80000000 is -2147483647 decimal. So the result is not zero.
>
> --
> ==================
> Remove the "x" from my email address
> Jerry Stuckle
> JDS Computer Training Corp.
> jstucklex@attglobal.net
> ==================[/color]


How can I port the php code, which return 0 (zero), and looks exactly
like this:

<?php
$a = 5543039447;
$b = 2147483648;
$result = ($a & $b);
echo "$result\n" ;
?>

to perl? In perl almost the exactly same code:

#!/usr/bin/perl
$a = 5543039447;
$b = 2147483648;
$result = ($a & $b);
print "$result\n" ;

returns 2147483648.

How do I have to modify the perl code, so that it will actually do a
bitwise and? I don't get - any workaround? Somethings I'm not getting
here? I'm using linux debian/sarge with an intel 32 bit prozessor.

Fritz

Jerry Stuckle
Guest
 
Posts: n/a
#14: Mar 4 '06

re: & behaves differently


fritz-bayer@web.de wrote:[color=blue]
> Jerry Stuckle wrote:
>[color=green]
>>d wrote:
>>[color=darkred]
>>>"Jerry Stuckle" <jstucklex@attglobal.net> wrote in message
>>>news:6vCdnYaBloS7MZXZnZ2dnUVZ_vidnZ2d@comcast.c om...
>>>
>>>
>>>>d wrote:
>>>>
>>>>
>>>>>"Jerry Stuckle" <jstucklex@attglobal.net> wrote in message
>>>>>news:P4qdnZ1ghuZKFJXZRVn-qw@comcast.com...
>>>>>
>>>>>
>>>>>
>>>>>>fritz-bayer@web.de wrote:
>>>>>>
>>>>>>
>>>>>>
>>>>>>>Hi,
>>>>>>>
>>>>>>>why does the php expression
>>>>>>>
>>>>>>>$result = 5543039447 & 2147483648;
>>>>>>>
>>>>>>>when executed evaluate to 0, whereas the perl expression
>>>>>>>
>>>>>>>$same = 5543039447 & 2147483648 ;
>>>>>>>
>>>>>>>evaluate to 2147483648 ???
>>>>>>>
>>>>>>>Fritz
>>>>>>>
>>>>>>
>>>>>>Because Perl is using 64 bit integers and PHP is using 32 bit integers.
>>>>>>
>>>>>>2147483648 is not a valid value in 32 bit arithmetic. The largest value
>>>>>>you can have is 2147483647.
>>>>>
>>>>>
>>>>>PHP interprets ints over 32 bits as floats, so they are valid.
>>>>>
>>>>>"If you specify a number beyond the bounds of the integer type, it will
>>>>>be interpreted as a float instead. Also, if you perform an operation that
>>>>>results in a number beyond the bounds of the integer type, a float will
>>>>>be returned instead."
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>>--
>>>>>>==================
>>>>>>Remove the "x" from my email address
>>>>>>Jerry Stuckle
>>>>>>JDS Computer Training Corp.
>>>>>>jstucklex@attglobal.net
>>>>>>==================
>>>>>
>>>>>
>>>>>
>>>>In most cases, yes. However, you cannot perform bit operations on a
>>>>float. It must be an integer type.
>>>>
>>>>So the value is converted back to an integer, and since it's outside the
>>>>bounds of a 32 bit integer the result is to strip off the high order bits.
>>>>
>>>>The result is zero.
>>>
>>>
>>>The result is zero regardless of whether that bit is there or not :)
>>>
>>>
>>>
>>>>Sometimes a little knowledge is worse than no knowledge at all.
>>>>
>>>
>>>
>>>Indeed.
>>>
>>>
>>>
>>>>--
>>>>==================
>>>>Remove the "x" from my email address
>>>>Jerry Stuckle
>>>>JDS Computer Training Corp.
>>>>jstucklex@attglobal.net
>>>>==================
>>>
>>>
>>>[/color]
>>Actually, 0x80000000 is -2147483647 decimal. So the result is not zero.
>>
>>--
>>==================
>>Remove the "x" from my email address
>>Jerry Stuckle
>>JDS Computer Training Corp.
>>jstucklex@attglobal.net
>>==================[/color]
>
>
>
> How can I port the php code, which return 0 (zero), and looks exactly
> like this:
>
> <?php
> $a = 5543039447;
> $b = 2147483648;
> $result = ($a & $b);
> echo "$result\n" ;
> ?>
>
> to perl? In perl almost the exactly same code:
>
> #!/usr/bin/perl
> $a = 5543039447;
> $b = 2147483648;
> $result = ($a & $b);
> print "$result\n" ;
>
> returns 2147483648.
>
> How do I have to modify the perl code, so that it will actually do a
> bitwise and? I don't get - any workaround? Somethings I'm not getting
> here? I'm using linux debian/sarge with an intel 32 bit prozessor.
>
> Fritz
>[/color]

I would suggest asking this in a Perl group. I'm a PHP programmer - I
know nothing about Perl.


--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
jstucklex@attglobal.net
==================
Tim Roberts
Guest
 
Posts: n/a
#15: Mar 5 '06

re: & behaves differently


"fritz-bayer@web.de" <fritz-bayer@web.de> wrote:[color=blue]
>
><?php
>$a = 5543039447;
>$b = 2147483648;
>$result = ($a & $b);
>echo "$result\n" ;
>?>
>
>to perl? In perl almost the exactly same code:
>
>#!/usr/bin/perl
>$a = 5543039447;
>$b = 2147483648;
>$result = ($a & $b);
>print "$result\n" ;
>
>returns 2147483648.
>
>How do I have to modify the perl code, so that it will actually do a
>bitwise and? I don't get - any workaround? Somethings I'm not getting
>here? I'm using linux debian/sarge with an intel 32 bit prozessor.[/color]

The basic problem here is that what you are asking for is nonsense. GIGO.

Both of your numbers are too large to fit into an unsigned 32-bit value.
When that happens, both languages will automatically convert to using
floating point to store those values. $a and $b are FLOATING POINT.

However, bitwise operations do not make sense for floating point values.
Thus, both languages must convert the floats back to 32-bit integers. But,
we already know that the values are too big for that. So, there is an
overflow. It just turns out that the two languages handle this overflow
differently.

PHP handles the overflow by throwing away the upper bits, leaving you with
only the bottom 32 bits of the converted value. Perl handles the overflow
by "pegging"; it returns 2^32-1, or 4,294,967,295. That value happens to
have all 32 bit set, so the bitwise "and" returns the second value.

If you need to handle integers larger than 32-bits in Perl, you can use the
Math::BigInt module to do that.
--
- Tim Roberts, timr@probo.com
Providenza & Boekelheide, Inc.
fritz-bayer@web.de
Guest
 
Posts: n/a
#16: Mar 5 '06

re: & behaves differently



Tim Roberts wrote:[color=blue]
> "fritz-bayer@web.de" <fritz-bayer@web.de> wrote:[color=green]
> >
> ><?php
> >$a = 5543039447;
> >$b = 2147483648;
> >$result = ($a & $b);
> >echo "$result\n" ;
> >?>
> >
> >to perl? In perl almost the exactly same code:
> >
> >#!/usr/bin/perl
> >$a = 5543039447;
> >$b = 2147483648;
> >$result = ($a & $b);
> >print "$result\n" ;
> >
> >returns 2147483648.
> >
> >How do I have to modify the perl code, so that it will actually do a
> >bitwise and? I don't get - any workaround? Somethings I'm not getting
> >here? I'm using linux debian/sarge with an intel 32 bit prozessor.[/color]
>
> The basic problem here is that what you are asking for is nonsense. GIGO.
>
> Both of your numbers are too large to fit into an unsigned 32-bit value.
> When that happens, both languages will automatically convert to using
> floating point to store those values. $a and $b are FLOATING POINT.
>
> However, bitwise operations do not make sense for floating point values.
> Thus, both languages must convert the floats back to 32-bit integers. But,
> we already know that the values are too big for that. So, there is an
> overflow. It just turns out that the two languages handle this overflow
> differently.
>
> PHP handles the overflow by throwing away the upper bits, leaving you with
> only the bottom 32 bits of the converted value. Perl handles the overflow
> by "pegging"; it returns 2^32-1, or 4,294,967,295. That value happens to
> have all 32 bit set, so the bitwise "and" returns the second value.
>
> If you need to handle integers larger than 32-bits in Perl, you can use the
> Math::BigInt module to do that.
> --
> - Tim Roberts, timr@probo.com
> Providenza & Boekelheide, Inc.[/color]

Thanks Tim! Any ideas how I could emulate the overflow, so that I get
the same overflow behaviour in perl, maybe by writting a function for
it?!

Oli Filth
Guest
 
Posts: n/a
#17: Mar 5 '06

re: & behaves differently


fritz-bayer@web.de said the following on 05/03/2006 11:39:[color=blue]
> Tim Roberts wrote:[color=green]
>>
>> PHP handles the overflow by throwing away the upper bits, leaving you with
>> only the bottom 32 bits of the converted value. Perl handles the overflow
>> by "pegging"; it returns 2^32-1, or 4,294,967,295. That value happens to
>> have all 32 bit set, so the bitwise "and" returns the second value.
>>
>> If you need to handle integers larger than 32-bits in Perl, you can use the
>> Math::BigInt module to do that.[/color]
>
> Thanks Tim! Any ideas how I could emulate the overflow, so that I get
> the same overflow behaviour in perl, maybe by writting a function for
> it?![/color]


Why would you want to do this? Either way, you're not going to get the
"correct" answer (in terms of mathematically correct).

Your best bet would be to go with the module that Tim suggested (or the
equivalent (?) in PHP - BCMath). Alternatively, re-think your algorithm
so that it doesn't require >32-bit numbers. After all, where are these
numbers going to come from?



--
Oli
fritz-bayer@web.de
Guest
 
Posts: n/a
#18: Mar 5 '06

re: & behaves differently



Oli Filth wrote:[color=blue]
> fritz-bayer@web.de said the following on 05/03/2006 11:39:[color=green]
> > Tim Roberts wrote:[color=darkred]
> >>
> >> PHP handles the overflow by throwing away the upper bits, leaving you with
> >> only the bottom 32 bits of the converted value. Perl handles the overflow
> >> by "pegging"; it returns 2^32-1, or 4,294,967,295. That value happens to
> >> have all 32 bit set, so the bitwise "and" returns the second value.
> >>
> >> If you need to handle integers larger than 32-bits in Perl, you can use the
> >> Math::BigInt module to do that.[/color]
> >
> > Thanks Tim! Any ideas how I could emulate the overflow, so that I get
> > the same overflow behaviour in perl, maybe by writting a function for
> > it?![/color]
>
>
> Why would you want to do this? Either way, you're not going to get the
> "correct" answer (in terms of mathematically correct).
>
> Your best bet would be to go with the module that Tim suggested (or the
> equivalent (?) in PHP - BCMath). Alternatively, re-think your algorithm
> so that it doesn't require >32-bit numbers. After all, where are these
> numbers going to come from?
>
>
>
> --
> Oli[/color]

Hi,

because I have to port the the following function including the
overflow behaviour from php to perl:

//unsigned shift right
function fillWithZeroes($a, $b)
{
$z = hexdec(80000000);
if ($z & $a)
{
$a = ($a>>1);
$a &= (~$z);
$a |= 0x40000000;
$a = ($a>>($b-1));
}
else
{
$a = ($a>>$b);
}
return $a;
}

Oli Filth
Guest
 
Posts: n/a
#19: Mar 5 '06

re: & behaves differently


fritz-bayer@web.de said the following on 05/03/2006 12:33:[color=blue]
> Oli Filth wrote:[color=green]
>> fritz-bayer@web.de said the following on 05/03/2006 11:39:[color=darkred]
>>> Tim Roberts wrote:
>>>> PHP handles the overflow by throwing away the upper bits, leaving you with
>>>> only the bottom 32 bits of the converted value. Perl handles the overflow
>>>> by "pegging"; it returns 2^32-1, or 4,294,967,295. That value happens to
>>>> have all 32 bit set, so the bitwise "and" returns the second value.
>>>>
>>>> If you need to handle integers larger than 32-bits in Perl, you can use the
>>>> Math::BigInt module to do that.
>>> Thanks Tim! Any ideas how I could emulate the overflow, so that I get
>>> the same overflow behaviour in perl, maybe by writting a function for
>>> it?![/color]
>>
>> Why would you want to do this? Either way, you're not going to get the
>> "correct" answer (in terms of mathematically correct).
>>[/color]
>
> because I have to port the the following function including the
> overflow behaviour from php to perl:
>
> //unsigned shift right
> function fillWithZeroes($a, $b)
> {
> $z = hexdec(80000000);
> if ($z & $a)
> {
> $a = ($a>>1);
> $a &= (~$z);
> $a |= 0x40000000;
> $a = ($a>>($b-1));
> }
> else
> {
> $a = ($a>>$b);
> }
> return $a;
> }[/color]

Why would you be concerned about behaviour in out-of-range input
conditions, as they're technically meaningless, and wouldn't be
relied-upon except in the most bizarre situations? What's more, if you
did make your Perl function consistent with PHP behaviour, it would then
be inconsistent with the rest of Perl's behaviour.

Anyway, I don't think the PHP behaviour Tim describes is consistent.
For instance, try this in PHP:

$a = 5543039444;
$b = $a * 10000000000;

echo $a . " => " . intval($a) . "\n";
echo $b . " => " . intval($b) . "\n";

PHP is clearly not just converting the floats to fully-represented
integers and retaining only the 32 LSBs.

--
Oli
fritz-bayer@web.de
Guest
 
Posts: n/a
#20: Mar 5 '06

re: & behaves differently



Oli Filth wrote:[color=blue]
> fritz-bayer@web.de said the following on 05/03/2006 12:33:[color=green]
> > Oli Filth wrote:[color=darkred]
> >> fritz-bayer@web.de said the following on 05/03/2006 11:39:
> >>> Tim Roberts wrote:
> >>>> PHP handles the overflow by throwing away the upper bits, leaving you with
> >>>> only the bottom 32 bits of the converted value. Perl handles the overflow
> >>>> by "pegging"; it returns 2^32-1, or 4,294,967,295. That value happens to
> >>>> have all 32 bit set, so the bitwise "and" returns the second value.
> >>>>
> >>>> If you need to handle integers larger than 32-bits in Perl, you can use the
> >>>> Math::BigInt module to do that.
> >>> Thanks Tim! Any ideas how I could emulate the overflow, so that I get
> >>> the same overflow behaviour in perl, maybe by writting a function for
> >>> it?!
> >>
> >> Why would you want to do this? Either way, you're not going to get the
> >> "correct" answer (in terms of mathematically correct).
> >>[/color]
> >
> > because I have to port the the following function including the
> > overflow behaviour from php to perl:
> >
> > //unsigned shift right
> > function fillWithZeroes($a, $b)
> > {
> > $z = hexdec(80000000);
> > if ($z & $a)
> > {
> > $a = ($a>>1);
> > $a &= (~$z);
> > $a |= 0x40000000;
> > $a = ($a>>($b-1));
> > }
> > else
> > {
> > $a = ($a>>$b);
> > }
> > return $a;
> > }[/color]
>
> Why would you be concerned about behaviour in out-of-range input
> conditions, as they're technically meaningless, and wouldn't be
> relied-upon except in the most bizarre situations? What's more, if you
> did make your Perl function consistent with PHP behaviour, it would then
> be inconsistent with the rest of Perl's behaviour.
>
> Anyway, I don't think the PHP behaviour Tim describes is consistent.
> For instance, try this in PHP:
>
> $a = 5543039444;
> $b = $a * 10000000000;
>
> echo $a . " => " . intval($a) . "\n";
> echo $b . " => " . intval($b) . "\n";
>
> PHP is clearly not just converting the floats to fully-represented
> integers and retaining only the 32 LSBs.
>
> --
> Oli[/color]

Well, I guess the program I'm porting relies on this strange behaviour.
That's for sure. I did not write it. I'm just trying to port it. Could
it be that php ocde above will convert those numbers to unsigned ints
so that no overflow takes place?!

Dana Cartwright
Guest
 
Posts: n/a
#21: Mar 5 '06

re: & behaves differently


<fritz-bayer@web.de> wrote in message
news:1141560298.729469.60990@v46g2000cwv.googlegro ups.com...[color=blue]
>I have to port the the following function including the
> overflow behaviour from php to perl:
>
> //unsigned shift right
> function fillWithZeroes($a, $b)
> {
> $z = hexdec(80000000);
> if ($z & $a)
> {
> $a = ($a>>1);
> $a &= (~$z);
> $a |= 0x40000000;
> $a = ($a>>($b-1));
> }
> else
> {
> $a = ($a>>$b);
> }
> return $a;
> }[/color]

Now that you've actually posted your code, it's possible to (finally)
understand something about the problem you're having.

First, I have to point out that whoever wrote this code did so under the
assumption that $a would be a 32-bit integer and $b would be in the range 0
to 31. The constant 80000000 is equivalent to the comment "This function
assumes $a is a 32-bit integer" (but see my note below). And if that's the
case, then $b is in the range 0 to 31 (otherwise the behaviour is
undefined).

Moreover, the author assumes that on the machine executing this code ">>"
might do sign bit propogation, but might not, and it might do sign bit
extension, or might not. Again, this is clear from the structure of the
code ("$a |= 0x40000000" deals with sign bit propogation, "$a &= (~$z)"
deals with sign bit extension).

But there are still puzzles in this code. The expression "hexdec(80000000)"
yields a floating point value in PHP (in modern PHP's--in older ones it's
undefined). As others have already pointed out, floating point has no
business being used in a function like this! This function was not written
to use floating point. The person who wrote it clearly assumed it was going
to handle 32-bit integers.

The entire function would make PERFECT sense if the opening line were "$z =
0x80000000"...is there any possibility that somebody changed it?

I cannot see where "overflow" comes into this function at all. Nothing in
it overflows.

Of course, PHP being PHP, you can pass whatever you want for $a and $b and
the function will doubtless deliver some result, probably without issuing
any error message. This is one of the nice things, and one of the not nice
things, about PHP. But if your goal is to reproduce that out-of-bounds
behaviour on some other machine, good luck. Actually, bad luck, because it
won't happen.

I don't know how PHP actually executes right shift (>>). But if it uses the
underlying hardware, which it might well do, be aware that when you
"overshift" (shift by the word width or more, so 32 or more, in this case),
most Intel chips do the shift modulo the word width, and most Motorola chips
use the value you supplied. So the expression $a >> 32 will typically give
you $a on an Intel chip, and 0 on a Motorola chip. Which is why you see
people warning you (and pay attention to their warning) that shifting by the
word width or more is UNDEFINED. Attempting to port such code is going to
bring you nothing but grief.

You need to take a deep breath, step back from this function, and examine
the code that calls it. Someplace the original author's assumptions are
being violated.

-Dana






fritz-bayer@web.de
Guest
 
Posts: n/a
#22: Mar 5 '06

re: & behaves differently


Thanks Dana and thanks to rest of the people who responded.

I have debug both scripts an figured out that the program breaks, when
it's processing the values

a=5496229061, b=13

The php script returns 146638 and the perl script 524287. So also the
operation $a = ($a >> $b) yields different values in php and perl.

Or could it be, that php is smart enough to create a unsigned integer,
wheras perl does not and therefore an overflow occurs? Anyway here you
have the possibiliy of an overflow depending on how $a is handled.

Do you think >> differs in perl and php or is it an overflow problem?

Dana Cartwright
Guest
 
Posts: n/a
#23: Mar 5 '06

re: & behaves differently


My e-mail address doesn't have a 2 in it.
<fritz-bayer@web.de> wrote in message
news:1141579228.695402.52300@i39g2000cwa.googlegro ups.com...[color=blue]
> Thanks Dana and thanks to rest of the people who responded.
>
> I have debug both scripts an figured out that the program breaks, when
> it's processing the values
>
> a=5496229061, b=13
>
> The php script returns 146638 and the perl script 524287. So also the
> operation $a = ($a >> $b) yields different values in php and perl.
>
> Or could it be, that php is smart enough to create a unsigned integer,
> wheras perl does not and therefore an overflow occurs? Anyway here you
> have the possibiliy of an overflow depending on how $a is handled.
>
> Do you think >> differs in perl and php or is it an overflow problem?[/color]

Please remember that this function is ONLY VALID when fed a $a that fits
within a 32-bit signed integer. As has been pointed out, 5,496,229,061
doesn't fit within a 32-bit signed int (limit is 2,147,483,647). Nor does
it fit within an unsigned 32-bit int (limit is 4,294,967,295). It isn't a
question of whether PHP is using signed or unsigned arithmetic. It is
surely being stored as a float of some sort (which will vary from one
computer to another).

Therefore, you simply cannot pass it to this function and expect predictable
results. Your results will depend upon the nitty-gritty details of the
language, the computer you're on, the version of the software you're
using...in short, you cannot pass this function 5496229061 and ask
meaningful questions about the results. It's not an overflow problem. It
does not depend on how >> works. It has to do with how numbers are
represented in memory.

If you have software that is feeding 5496229061 to this function, then you
have a HUGE problem. Evidently the software depends upon the specific value
that this function HAPPENS TO RETURN when run on a CERTAIN HARDWARE PLATFORM
on a PARTICULAR VERSION OF PHP. Aside from the issue of porting it to perl,
I am certain that this software will break (in unpredictable ways) simply by
the passage of time, because if you try to run it on a different computer,
it will likely break. If you upgrade PHP, it will likely break. And so on
and so forth. This is a time bomb that will sooner or later detonate.

You cannot easily fix this problem by messing around with this function.
Your software is breaking the rules, and you are suffering the consequences.

You could study the floating point representation of 5,496,229,061 and see
if the results you are getting can be predicted from that (this should be
possible, since computers are not whimsical). You would need to look at the
PHP code that implements >> and see what it does with a floating point (this
is where open source is *really* handy). And you could try to force perl to
do its arithmetic the same way. And you could meticulously document the
resulting code. It should be possible to do. It's what I would do if this
were my problem to solve and I wasn't able to fix the real problem, which is
that some idiot wrote code that is passing bogus values to this function.

-Dana


fritz-bayer@web.de
Guest
 
Posts: n/a
#24: Mar 5 '06

re: & behaves differently


Hi Dana,

the complete code of the php, which I`m supposed to port to perl can be
found at http://www.googlecommunity.com/scrip...e-pagerank.php

It actually computes the pagerank of a website. Most of the script is
calculating a checksum, which is needed to calculate the pagerank.

It's really strange the code, but my job is just to port it, but it's
not so easy as you can see?

Oli Filth
Guest
 
Posts: n/a
#25: Mar 5 '06

re: & behaves differently


fritz-bayer@web.de said the following on 05/03/2006 21:06:[color=blue]
> Hi Dana,
>
> the complete code of the php, which I`m supposed to port to perl can be
> found at http://www.googlecommunity.com/scrip...e-pagerank.php
>
> It actually computes the pagerank of a website. Most of the script is
> calculating a checksum, which is needed to calculate the pagerank.
>
> It's really strange the code, but my job is just to port it, but it's
> not so easy as you can see?
>[/color]

Basically, PHP doesn't do unsigned arithmetic. This algorithm probably
originated in C or something similar, where you can specify unsigned
data types and everything will work fine. The implementation this guy
created relies on the current conversions occurring in PHP; on a 64-bit
platform this would probably fail.

However:

http://tumanov.com/entry/209
It's talking about VBScript, but the problem he describes is identical.

--
Oli
ColdShine
Guest
 
Posts: n/a
#26: Mar 5 '06

re: & behaves differently


> //unsigned shift right[color=blue]
> function fillWithZeroes($a, $b)
> {
> $z = hexdec(80000000);
> if ($z & $a)
> {
> $a = ($a>>1);
> $a &= (~$z);
> $a |= 0x40000000;
> $a = ($a>>($b-1));
> }
> else
> {
> $a = ($a>>$b);
> }
> return $a;
> }[/color]

This should handle an arbitrary number of bits for $a, allowing $b to be
greater than the number of machine word bits.

// Assuming 32-bit (1 sign) integer length.
function fillWithZeroes($a, $b)
{
// In PHP you could use is_float($a), but I don't know
// the equivalent Perl function.
if ($a > 0x7FFFFFFF)
{
// It is some FP number, must emulate shift with division.
$d = exp(2, $b);
$a = round($a / $d);
// Return int if possible.
if ($a <= 0x7FFFFFFF)
$a = (int)$a;
}
else
$a >>= $b;
return $a;
}

This yelds correct results as long as FP numbers have enugh precision. This
is obviously NOT a safe assumption; yet if FP numbers have 53 + 1
significand bits (64-bits IEEE FP), this fillWithZeroes should be able to
handle numbers from 0 to 2^54 - 1.

--
ColdShine

"Experience is a hard teacher: she gives the test first, the lesson
afterwards." - Vernon Sanders law


fritz-bayer@web.de
Guest
 
Posts: n/a
#27: Mar 6 '06

re: & behaves differently



ColdShine wrote:[color=blue][color=green]
> > //unsigned shift right
> > function fillWithZeroes($a, $b)
> > {
> > $z = hexdec(80000000);
> > if ($z & $a)
> > {
> > $a = ($a>>1);
> > $a &= (~$z);
> > $a |= 0x40000000;
> > $a = ($a>>($b-1));
> > }
> > else
> > {
> > $a = ($a>>$b);
> > }
> > return $a;
> > }[/color]
>
> This should handle an arbitrary number of bits for $a, allowing $b to be
> greater than the number of machine word bits.
>
> // Assuming 32-bit (1 sign) integer length.
> function fillWithZeroes($a, $b)
> {
> // In PHP you could use is_float($a), but I don't know
> // the equivalent Perl function.
> if ($a > 0x7FFFFFFF)
> {
> // It is some FP number, must emulate shift with division.
> $d = exp(2, $b);
> $a = round($a / $d);
> // Return int if possible.
> if ($a <= 0x7FFFFFFF)
> $a = (int)$a;
> }
> else
> $a >>= $b;
> return $a;
> }
>
> This yelds correct results as long as FP numbers have enugh precision. This
> is obviously NOT a safe assumption; yet if FP numbers have 53 + 1
> significand bits (64-bits IEEE FP), this fillWithZeroes should be able to
> handle numbers from 0 to 2^54 - 1.
>
> --
> ColdShine
>
> "Experience is a hard teacher: she gives the test first, the lesson
> afterwards." - Vernon Sanders law[/color]

Hi Coldhine, thanks for the workaround. I had to slightly change the
code, since perl does not have a rounding function and have now:

sub zeroFill2()
{
my ($a, $b) = @_;
# In PHP you could use is_float($a), but I don't know
# the equivalent Perl function.
if ($a > 0x7FFFFFFF)
{
# It is some FP number, must emulate shift with division.
$d = 2 ** $b;
$a = round($a / $d);

# Return int if possible.
if ($a <= 0x7FFFFFFF)
{
return int($a);
}
}
else
{
$a = ($a >> $b);
}
return $a;

}

sub round()
{
my ($number) = @_;
return int($number + .5 * ($number <=> 0));
}

Problem still remains so. This function returns 679118 instead of the
needed 154830. What should I change, so that it will return the right
numbers?

Tim Roberts
Guest
 
Posts: n/a
#28: Mar 7 '06

re: & behaves differently


Oli Filth <catch@olifilth.co.uk> wrote:[color=blue]
>
>Anyway, I don't think the PHP behaviour Tim describes is consistent.
>For instance, try this in PHP:
>
> $a = 5543039444;
> $b = $a * 10000000000;
>
> echo $a . " => " . intval($a) . "\n";
> echo $b . " => " . intval($b) . "\n";
>
>PHP is clearly not just converting the floats to fully-represented
>integers and retaining only the 32 LSBs.[/color]

Actually, you're seeing an artifact of the design of the x86 FPU here. With
any fewer zeros, your code will print a number.

I looked up the PHP code; it is doing a simple C cast to unsigned long, and
writing the equivalent C program gets the same result:

int main(void)
{
double a = 5543039444;
double b = a * 10000000000;
printf( "%f %d\n", b, (unsigned long)b);
return 0;
}

C:\tmp>x
55430394439999996000.000000 0

C:\tmp>

The reason is that the mantissa in your example requires more than 64 bits,
which means it can no longer be represented exactly in an 80-bit FPU
register. In that case, the "fist" instruction raises an exception and
returns the "most negative integer". For an unsigned long, that is 0.
--
- Tim Roberts, timr@probo.com
Providenza & Boekelheide, Inc.
Tim Streater
Guest
 
Posts: n/a
#29: Mar 7 '06

re: & behaves differently


In article <1141409437.320652.250950@t39g2000cwt.googlegroups .com>,
"fritz-bayer@web.de" <fritz-bayer@web.de> wrote:
[color=blue]
> Are you serious about this? I mean you are right that it should be
> zero, but could it be, that I have to use a different expression? Or
> use a function instead of using the & ? Have you tried it yourself on
> your machine? Do you get the same result?[/color]

If I were given such a porting job, I would be inclined to take a step
back and see what the purpose of the function was. As has been
eloquently pointed out, you are unlikely to succeed if all you do is try
to port the code in a mechanical way.

Is the function called in one place in the code? In many? Figure out
what you want the function to do and only then worry about how to do it.

-- tim
CrashRoX
Guest
 
Posts: n/a
#30: Mar 15 '06

re: & behaves differently


I found a perl version: http://www.everyscript.de/PRank.htm

CrashRoX
Guest
 
Posts: n/a
#31: Mar 15 '06

re: & behaves differently


I found a perl version: http://www.everyscript.de/PRank.htm

Can you convert that back to PHP for 64 bit machines?

Closed Thread