1. Advertising
    y u no do it?

    Advertising (learn more)

    Advertise virtually anything here, with CPM banner ads, CPM email ads and CPC contextual links. You can target relevant areas of the site and show ads based on geographical location of the user if you wish.

    Starts at just $1 per CPM or $0.10 per CPC.

Quick Question Concerning Byte Shifting?

Discussion in 'PHP' started by x11joex11, Feb 12, 2008.

  1. #1
    Hey say I have the following code.

    $test = 2468462055;
    $test >>= 2;
    echo $test;

    You would expect it to show 617115513, as byte shifting to the right is dividing by 2.

    However it shows -456626311 for me. What is going on?

    Best,
    - Joe~
     
    x11joex11, Feb 12, 2008 IP
  2. stoli

    stoli Peon

    Messages:
    69
    Likes Received:
    14
    Best Answers:
    0
    Trophy Points:
    0
    #2
    Probably because your $test value exceeds PHP's maximum signed integer range.

    32 bit systems have a maximum signed integer range of -2147483648 to 2147483647.

    You can check your maximum int size thusly:
    <?php
    echo PHP_INT_MAX;
    ?>
    PHP:
     
    stoli, Feb 12, 2008 IP
  3. x11joex11

    x11joex11 Peon

    Messages:
    106
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #3
    I understand now that is probably why, but even if that is the case, why the -456626311, how did it get to that value mathematically speaking? It's important since a PHP script I'm writing is supposed to have let this happen.
     
    x11joex11, Feb 12, 2008 IP
  4. walkere

    walkere Active Member

    Messages:
    112
    Likes Received:
    7
    Best Answers:
    0
    Trophy Points:
    58
    #4
    I'd assume that PHP int's "wrap around" at some point. So when you create a value higher than the max value, you revert to the lowest possible negative value.

    I just tested this assumption, and it appears to be true. Here's what I used to check it...

    echo PHP_INT_MAX;  //  2147483647
    echo (int) (2147483647); // 2147483647
    echo (int) (2147483647 + 1); // -2147483648
    PHP:
    So when you get to one more than the maximum, it reverts to the minimum (or negative one times the maximum).

    Also note that I was using (int) to force the int type. You can work with bigger numbers - PHP will automatically convert them to floats.

    - Walkere
     
    walkere, Feb 12, 2008 IP
  5. x11joex11

    x11joex11 Peon

    Messages:
    106
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #5
    Interesting, thanks for that valuable insight! I'll keep working at my program and post if I run into further problems. I'm not so sure how dividing by 2 caused the number to wrap around though but perhaps because it was already past it limits it went into the negatives and then divided?
     
    x11joex11, Feb 12, 2008 IP
  6. stoli

    stoli Peon

    Messages:
    69
    Likes Received:
    14
    Best Answers:
    0
    Trophy Points:
    0
    #6
    Your test value is over the maximum integer size so it does wrap around into negatives when typecast to an int, as walkere said.

    So:
    (-2147483648 + (2468462055 - 2147483648)) == -1826505241
    and when -1826505241 is right shifted twice you get (as you would normally expect) -456626311 which is your mystery number.

    The following demonstrates it:
    <?php
    $test = 2468462055;
    echo "Test value: $test<br>\n";
    echo "Test value typecast to int: ".(int)$test."<br>\n";
    echo "Typecasting to int takes how much the test value is over the maximum int size and adds it to the minumum int size:<br>\n (-2147483648 + (\$test - 2147483648)) = ".(-2147483648 + ($test - 2147483648))."<br>\n";
    echo "Test value typecast to int divided by 2 twice: ".((((int)$test)/2)/2)."<br>\n";
    echo "Test value typecast to int right shifted twice: ".((int)$test>>2)."<br>\n";
    ?>
    PHP:
    Normally integers that exceed the maximum integer size are automatically converted to floats which allow for a greater range. You can't bit shift a float though so your test value gets automatically type cast to an int before shifting it.
     
    stoli, Feb 13, 2008 IP
    x11joex11 likes this.