You are here: Re: & behaves differently « PHP Programming Language « IT news, forums, messages
Re: & behaves differently

Posted by Dana Cartwright on 11/03/86 11:41

<fritz-bayer@web.de> wrote in message
news:1141560298.729469.60990@v46g2000cwv.googlegroups.com...
>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;
> }

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

 

Navigation:

[Reply to this message]


Удаленная работа для программистов  •  Как заработать на Google AdSense  •  England, UK  •  статьи на английском  •  PHP MySQL CMS Apache Oscommerce  •  Online Business Knowledge Base  •  DVD MP3 AVI MP4 players codecs conversion help
Home  •  Search  •  Site Map  •  Set as Homepage  •  Add to Favourites

Copyright © 2005-2006 Powered by Custom PHP Programming

Сайт изготовлен в Студии Валентина Петручека
изготовление и поддержка веб-сайтов, разработка программного обеспечения, поисковая оптимизация