473,394 Members | 1,724 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,394 software developers and data experts.

confusing >> results

Using >> normally shifts bits to the right x number of times, where x
is specified by the programmer. As an example, 0x40000000 >> 8 yields
0x00400000. This makes me wonder... why doesn't the same thing happen
with 0x80000000 >> 8? The number it yields is 0xff800000 - not
0x00800000. The following script better demonstrates this:

<?
echo sprintf('%08x',0x40000000 >> 8)."\n";
echo sprintf('%08x',0x80000000 >> 8);
?>

Anyway, any ideas?

Jan 16 '06 #1
12 1591
yawnmoth wrote:
Using >> normally shifts bits to the right x number of times, where x
is specified by the programmer. As an example, 0x40000000 >> 8 yields
0x00400000. This makes me wonder... why doesn't the same thing happen
with 0x80000000 >> 8? The number it yields is 0xff800000 - not
0x00800000. The following script better demonstrates this:

<?
echo sprintf('%08x',0x40000000 >> 8)."\n";
echo sprintf('%08x',0x80000000 >> 8);
?>

Anyway, any ideas?


My guess is that PHP sees 0x8000000 as a *signed* integer
Jan 16 '06 #2
Palle Hansen wrote:
yawnmoth wrote:
Using >> normally shifts bits to the right x number of times, where x
is specified by the programmer. As an example, 0x40000000 >> 8 yields
0x00400000. This makes me wonder... why doesn't the same thing happen
with 0x80000000 >> 8? The number it yields is 0xff800000 - not
0x00800000. The following script better demonstrates this:

<?
echo sprintf('%08x',0x40000000 >> 8)."\n";
echo sprintf('%08x',0x80000000 >> 8);
?>

Anyway, any ideas?


My guess is that PHP sees 0x8000000 as a *signed* integer


Seems like you're right, Palle.

I tested with this code:

<?php
header('Content-Type: text/plain');

$t = 0x80000000;
echo $t-1, '; ', $t, '; ', $t + 1, "\n";
var_dump($t);

/*********
* <quote src="http://www.php.net/unpack">
* CAUTION
* Note that PHP internally stores integral values as signed. If
* you unpack a large unsigned long and it is of the same size as
* PHP internally stored values the result will be a negative
* number even though unsigned unpacking was specified.
* </quote>
*********/

/* N: unsigned long (always 32 bit, big endian byte order) */
$unsignedlong = unpack('N', "\x80\x00\x00\x00");
var_dump($unsignedlong);
?>
--
Mail to my "From:" address is readable by all at http://www.dodgeit.com/
== ** ## !! ------------------------------------------------ !! ## ** ==
TEXT-ONLY mail to the whole "Reply-To:" address ("My Name" <my@address>)
may bypass my spam filter. If it does, I may reply from another address!
Jan 16 '06 #3

Palle Hansen wrote:
yawnmoth wrote:
Using >> normally shifts bits to the right x number of times, where x
is specified by the programmer. As an example, 0x40000000 >> 8 yields
0x00400000. This makes me wonder... why doesn't the same thing happen
with 0x80000000 >> 8? The number it yields is 0xff800000 - not
0x00800000. The following script better demonstrates this:

<?
echo sprintf('%08x',0x40000000 >> 8)."\n";
echo sprintf('%08x',0x80000000 >> 8);
?>

Anyway, any ideas?


My guess is that PHP sees 0x8000000 as a *signed* integer


Why should >> even be concerned with whether or not integers are signed?

Jan 16 '06 #4
Palle Hansen wrote:
yawnmoth wrote:
Using >> normally shifts bits to the right x number of times, where x
is specified by the programmer. As an example, 0x40000000 >> 8 yields
0x00400000. This makes me wonder... why doesn't the same thing happen
with 0x80000000 >> 8? The number it yields is 0xff800000 - not
0x00800000. The following script better demonstrates this:

<?
echo sprintf('%08x',0x40000000 >> 8)."\n";
echo sprintf('%08x',0x80000000 >> 8);
?>

Anyway, any ideas?


My guess is that PHP sees 0x8000000 as a *signed* integer


No, PHP sees 0x80000000 as a double, because the number is beyond the
range of an integer (on 32 bit systems).

Jan 16 '06 #5
Chung Leong wrote:
Palle Hansen wrote:
yawnmoth wrote:
Using >> normally shifts bits to the right x number of times, where x
is specified by the programmer. As an example, 0x40000000 >> 8 yields
0x00400000. This makes me wonder... why doesn't the same thing happen
with 0x80000000 >> 8? The number it yields is 0xff800000 - not
0x00800000. The following script better demonstrates this:

<?
echo sprintf('%08x',0x40000000 >> 8)."\n";
echo sprintf('%08x',0x80000000 >> 8);
?>

Anyway, any ideas?


My guess is that PHP sees 0x8000000 as a *signed* integer

No, PHP sees 0x80000000 as a double, because the number is beyond the
range of an integer (on 32 bit systems).


No, 0x80000000 is exactly 32 bits and is taken as a signed integer.

--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
js*******@attglobal.net
==================
Jan 16 '06 #6
yawnmoth wrote:
Palle Hansen wrote:
yawnmoth wrote:
Using >> normally shifts bits to the right x number of times, where x
is specified by the programmer. As an example, 0x40000000 >> 8 yields
0x00400000. This makes me wonder... why doesn't the same thing happen
with 0x80000000 >> 8? The number it yields is 0xff800000 - not
0x00800000. The following script better demonstrates this:

<?
echo sprintf('%08x',0x40000000 >> 8)."\n";
echo sprintf('%08x',0x80000000 >> 8);
?>

Anyway, any ideas?


My guess is that PHP sees 0x8000000 as a *signed* integer

Why should >> even be concerned with whether or not integers are signed?


Well, it's got to make a decision one way or the other. As a signed
integer, 0x80000000 is -2,147,483,648. Shift right one bit and you get
0xc0000000, which is 1,073,741,824 - the correct result for dividing by 2.

--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
js*******@attglobal.net
==================
Jan 16 '06 #7
Chung Leong wrote:
Palle Hansen wrote:
yawnmoth wrote:
> <?
> echo sprintf('%08x',0x40000000 >> 8)."\n";
> echo sprintf('%08x',0x80000000 >> 8);
> ?>
My guess is that PHP sees 0x8000000 as a *signed* integer
No, PHP sees 0x80000000 as a double, because the number is beyond the
range of an integer (on 32 bit systems).


Right, but the >> operator "casts" the float to an int.

~$ php -r '$x = 0x80000000; var_dump($x);'
float(2147483648)

~$ php -r '$x = 0x80000000 >> 0; var_dump($x);'
int(-2147483648)

--
If you're posting through Google read <http://cfaj.freeshell.org/google>
Jan 16 '06 #8
yawnmoth wrote:
Why should >> even be concerned with whether or not integers are signed?


~$ php -r 'echo -2 << 2, "\n";'
-8
~$ php -r 'echo -8 >> 2, "\n";'
-2

--
If you're posting through Google read <http://cfaj.freeshell.org/google>
Jan 16 '06 #9
Pedro Graca wrote:
yawnmoth wrote:
Why should >> even be concerned with whether or not integers are signed?


~$ php -r 'echo -8 >> 2, "\n";'


I forgot the rest of the post ...

Let's say -8 in binary is (ignore the spaces)
MSB == 10000000 00000000 00000000 00001000 == LSB

if you shift this right without concern for the sign, you get
MSB == 00100000 00000000 00000000 00000010 == LSB

which is 536870914
Do you think -8 >> 2 (-8 divided by 4) should equal 536870914? :)

--
If you're posting through Google read <http://cfaj.freeshell.org/google>
Jan 16 '06 #10
Pedro Graca wrote:
Pedro Graca wrote:
yawnmoth wrote:
Why should >> even be concerned with whether or not integers are signed?


~$ php -r 'echo -8 >> 2, "\n";'

I forgot the rest of the post ...

Let's say -8 in binary is (ignore the spaces)
MSB == 10000000 00000000 00000000 00001000 == LSB

if you shift this right without concern for the sign, you get
MSB == 00100000 00000000 00000000 00000010 == LSB

which is 536870914
Do you think -8 >> 2 (-8 divided by 4) should equal 536870914? :)


But -8 binary is:

11111111 11111111 11111111 11111000

--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
js*******@attglobal.net
==================
Jan 16 '06 #11
Jerry Stuckle wrote:
Pedro Graca wrote:

Let's say -8 in binary is (ignore the spaces)
MSB == 10000000 00000000 00000000 00001000 == LSB

if you shift this right without concern for the sign, you get
MSB == 00100000 00000000 00000000 00000010 == LSB

which is 536870914
Do you think -8 >> 2 (-8 divided by 4) should equal 536870914? :)


But -8 binary is:

11111111 11111111 11111111 11111000


Indeed it is (on my machines).
However some other machine running PHP could use sign-and-magnitude
representation of negative numbers instead of two's complement.
For that machine my reasoning above stands :-)

My book on C (The C Programming Language, Kernighan & Ritchie) says this
about >>

<quote>
Right shifting a signed quantity will fill with sign bits
("arithmetic shift") on some machines and with 0-bits
("logical shift") on others.
</quote>

So, taking into account that PHP is written in C, I guess the effect of
0x80000000 >> 8
is implementation defined (can be 0xff800000 on some (most) machines
and 0x00800000 on other machines)

And as PHP does not have C's `unsigned long int` it's best to avoid
right shifting negative values.

--
If you're posting through Google read <http://cfaj.freeshell.org/google>
Jan 17 '06 #12
Pedro Graca wrote:
Jerry Stuckle wrote:
Pedro Graca wrote:
Let's say -8 in binary is (ignore the spaces)
MSB == 10000000 00000000 00000000 00001000 == LSB

if you shift this right without concern for the sign, you get
MSB == 00100000 00000000 00000000 00000010 == LSB

which is 536870914
Do you think -8 >> 2 (-8 divided by 4) should equal 536870914? :)


But -8 binary is:

11111111 11111111 11111111 11111000

Indeed it is (on my machines).
However some other machine running PHP could use sign-and-magnitude
representation of negative numbers instead of two's complement.
For that machine my reasoning above stands :-)

My book on C (The C Programming Language, Kernighan & Ritchie) says this
about >>

<quote>
Right shifting a signed quantity will fill with sign bits
("arithmetic shift") on some machines and with 0-bits
("logical shift") on others.
</quote>

So, taking into account that PHP is written in C, I guess the effect of
0x80000000 >> 8
is implementation defined (can be 0xff800000 on some (most) machines
and 0x00800000 on other machines)

And as PHP does not have C's `unsigned long int` it's best to avoid
right shifting negative values.


Pedro,

Just because it's undefined in C doesn't mean it has to be in PHP.
Different languages can have different rules.

And everything is eventually built on machine language anyway.

--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
js*******@attglobal.net
==================
Jan 17 '06 #13

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
by: Arne Schirmacher | last post by:
I want to display a MySQL database field that can contain HTML markup. If I use <esql:get-string> then I get all of the database field, but all tags are escaped which is not what I want. If I use...
2
by: franklini | last post by:
hello people i. can anybody help me, i dont know what is wrong with this class. it has something to do with the me trying to override the input output stream. if i dont override it, it works fine....
2
by: 2obvious | last post by:
Below is a cut-and-paste code example that runs. It demonstrates some results which confuse me. It uses a DataGrid to make a table with 12 rows, each containing a TextBox and a CustomValidator....
11
by: Joe | last post by:
Hello All, I have an ASP.NET page with one Textbox (SearchTextBox) and one ImageButton (SearchButton) server controls. The user can type search text in SearchTextBox and click SearchButton and...
3
by: Iwanow | last post by:
Hello! My goal is to develop a program that opens a bitmap, copies its pixels to an ArrayList in order to perform some complex calculations (edge detection, Hough transform etc.), and save...
4
by: jienweiwu | last post by:
The following is correct... #include <iostream> using namespace std; int main() { double BMI,height,weight; cout<<"Welcome to the BMI calculator!\n\n"; cout<<"Enter your weight(kilos): ";
28
by: Kent Feiler | last post by:
1. Here's some html from a W3C recommendations page. <P>aaaaaaaaa<DIV>bbbbbbbbb</DIV><DIV>cccccccc<P>dddddddd</DIV> 2.Although I didn't think it would make any difference, I tried it with the...
6
by: =?iso-8859-2?Q?K=F8i=B9tof_=AEelechovski?= | last post by:
At <http://jibbering.com/faq/index.html#FAQ4_41> IS Microsoft introduced a shortcut that can be used to reference elements which include an ID attribute where the ID becomes a global variable....
10
by: jason.cipriani | last post by:
Is there any difference between declaring a template parameter as a "typename" or a "class"? E.g. template <class TT f() { } template <typename TT g() { } Thanks, Jason
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.