Page 1 of 2 12 LastLast
Results 1 to 10 of 18

Thread: & number

  1. #1
    Join Date
    Mar 2005
    Location
    SE PA USA
    Posts
    30,495
    Thanks
    82
    Thanked 3,449 Times in 3,410 Posts
    Blog Entries
    12

    Default & number

    I was just helping out someone in this forum with a syntax error. That went OK, but their code also had something in it that I don't understand:

    PHP Code:
    $bigIndex rand(0, (count($quotations) -1)) & 65534
    I get that it's setting the var $bigIndex to a random number based upon the length of the $quotations array. What I don't understand is the exact meaning of the:

    & 65534

    part.

    It appears to make it so that the number returned is even, and it appears that it at least allows that number to be within the range specified by:

    0, (count($quotations) -1

    without going over, even though that range is less than and is far lower than 65534.

    Anyone can tell me what it means?
    - John
    ________________________

    Show Additional Thanks: International Rescue Committee - Donate or: The Ocean Conservancy - Donate or: PayPal - Donate

  2. #2
    Join Date
    Jan 2007
    Location
    Davenport, Iowa
    Posts
    2,385
    Thanks
    100
    Thanked 113 Times in 111 Posts

    Default

    At first glance it looks like a unicode value. The range goes from 0 to 65535 and is expressed like this:

    Code:
    <?php
    echo "xx&# 65533;xx<br><br>";
    ?>
    I used 65533 as it is the last one that you can use. 65534 and 65535 are reserved and not to be used. ref

    EDIT: There is not really a space between the # and 65533, but I added it because this forum expresses unicode as actual unicode even if it is placed in PHP tags.
    Last edited by james438; 07-27-2012 at 05:11 AM.
    To choose the lesser of two evils is still to choose evil. My personal site

  3. #3
    Join Date
    Mar 2005
    Location
    SE PA USA
    Posts
    30,495
    Thanks
    82
    Thanked 3,449 Times in 3,410 Posts
    Blog Entries
    12

    Default

    I think you're on to something, because if I use 65536, which you say is out of range, $bigIndex is always 0. That would tend to indicate that the expression is a bitwise comparison that returns a number and that 65536 is false.

    I do know that in this case it is somehow assuring that $bigIndex must be even and that it can at least be as high as the total number of entries in the array, yet no higher.

    If I remove it entirely:

    Code:
    $bigIndex = rand(0, (count($quotations) -1));
    $bigIndex can be odd. If I use a lower number (here the actual length of the array):

    Code:
    $bigIndex = rand(0, (count($quotations) -1)) & 572;
    $bigIndex has to be even again but now cannot be more than a certain amount, though since it's random, I'm not sure exactly, but it's obviously much less than the number used.

    So it obviously set a limit. If the number is odd, then $bigIndex can be even or odd.

    So I basically understand its function here. Just not what it's called or how it's working.

    In simplest terms, it rounds down to the nearest even number.
    Last edited by jscheuer1; 07-27-2012 at 07:18 AM. Reason: add last line
    - John
    ________________________

    Show Additional Thanks: International Rescue Committee - Donate or: The Ocean Conservancy - Donate or: PayPal - Donate

  4. #4
    Join Date
    Jan 2007
    Location
    Davenport, Iowa
    Posts
    2,385
    Thanks
    100
    Thanked 113 Times in 111 Posts

    Default

    There may be a reason for the even/odd setting, but I wonder if it is an error in his code. It depends on what he is trying to do, though.

    It might be interesting to create a tiny script that will randomly generate a small set of unicode characters, but there are still very large gaps in unicode that have not been assigned yet.

    EDIT: Silly me. The name of the string itself is $quotations, so it probably has to do with some sort of counting or generating of sets of quotation marks, which would always be an even number.
    To choose the lesser of two evils is still to choose evil. My personal site

  5. #5
    Join Date
    Mar 2006
    Location
    Illinois, USA
    Posts
    12,164
    Thanks
    265
    Thanked 690 Times in 678 Posts

    Default

    It's a bitwise operator. 65536 is 16^4 or 2^16.

    Unfortunately I've never had the need to understand how to use bitwise operators so I don't really understand them. Here's the php.net page though:
    http://php.net/manual/en/language.operators.bitwise.php

    It looks like the goal is to retain all bits in the random number that also correspond to a large power-of-2 number-- the goal seems to be finding a number that is a power of 2 (or is it just divisible by two? I'm not sure). Since 2^16 is a very large number, it effectively does this even though technically there are larger numbers (but not relevant in this case).
    Daniel - Freelance Web Design | <?php?> | <html>| español | Deutsch | italiano | português | català | un peu de français | some knowledge of several other languages: I can sometimes help translate here on DD | Linguistics Forum

  6. #6
    Join Date
    Mar 2005
    Location
    SE PA USA
    Posts
    30,495
    Thanks
    82
    Thanked 3,449 Times in 3,410 Posts
    Blog Entries
    12

    Default

    $quotations is an array of quotations and attributions. The quotations are even numbers the attributions are odd. The entire function returns the $bigIndex followed by the $bigIndex + 1. So as long as the number returned is even, you get a quote followed by it's author. If the expression:

    Code:
    $bigIndex = rand(0, (count($quotations) -1)) & 65534;
    returns an odd number, which it can if we remove the bitwise operation, then the author is listed first, followed by the next quotation.

    So, again in simplest terms, it's rounding down to the next even number.

    I tried it with actual numbers. That's what it does. As to why it does that, and what it's called, that's what I want to know. I think I have my second answer. It's a bitwise operation. How it does what it does here is still a bit opaque to me.

    In the PHP manual it says:

    Code:
    Example		Name		Result
    $a & $b		And	Bits that are set in both $a and $b are set.
    So it's staring me in the face, I'm just not seeing it.
    Last edited by jscheuer1; 07-27-2012 at 08:01 AM. Reason: detail
    - John
    ________________________

    Show Additional Thanks: International Rescue Committee - Donate or: The Ocean Conservancy - Donate or: PayPal - Donate

  7. #7
    Join Date
    Mar 2006
    Location
    Illinois, USA
    Posts
    12,164
    Thanks
    265
    Thanked 690 Times in 678 Posts

    Default

    I think we posted at the same time, John.

    I'm not sure I exactly get it either, but it's close enough. Bitwise operators are very low level so they are processed quickly and are very efficient for simple mathematical operations. (I find them almost impossible to read, but that's irrelevant.) So it's just a trick to get an even number (since that's what your tests show), using the comparison of a known even number.

    But I didn't notice above that it's 65534 not 65536, so I don't know what's going on there. Maybe there's a 0 implicit so it's really 65535 (as in array indices), but then I don't know there that one extra 1 is going.
    Daniel - Freelance Web Design | <?php?> | <html>| español | Deutsch | italiano | português | català | un peu de français | some knowledge of several other languages: I can sometimes help translate here on DD | Linguistics Forum

  8. #8
    Join Date
    Mar 2005
    Location
    SE PA USA
    Posts
    30,495
    Thanks
    82
    Thanked 3,449 Times in 3,410 Posts
    Blog Entries
    12

    Default

    Quote Originally Posted by djr33 View Post
    It's a bitwise operator. 65536 is 16^4 or 2^16.
    What you're saying there makes sense. I had figured out it was a bitwise operator, but not how it was doing what it was doing. That and the rest (quoted below) adds a clue, enough of one that I feel I've almost got it.

    Quote Originally Posted by djr33 View Post
    It looks like the goal is to retain all bits in the random number that also correspond to a large power-of-2 number-- the goal seems to be finding a number that is a power of 2 (or is it just divisible by two? I'm not sure). Since 2^16 is a very large number, it effectively does this even though technically there are larger numbers (but not relevant in this case).
    The only thing is that it's 65534. If it's 65536, it's out of range somehow (almost certainly because it has something to do with Unicode) and always returns false/0.

    If it's 65535, it's in range, but can be either even or odd, so has no discernible effect.

    By experimenting though, if the number is too low, it limits the upper range of the result. So the bits being shared is somehow the key. I guess I need more info on just what a bit is in this case, and on how Unicode ties in.

    It smells like a special case and/or trick with math and/or something that relies upon a limitation of PHP sort of thing.

    If I do:

    Code:
    $bigIndex = 571 & 65532;
    I get 568. But with (or 65530, strangely):

    Code:
    $bigIndex = 571 & 65534;
    I get 570 - the desired result in this case. So it looks like a Swiss cheese effect.
    - John
    ________________________

    Show Additional Thanks: International Rescue Committee - Donate or: The Ocean Conservancy - Donate or: PayPal - Donate

  9. #9
    Join Date
    Mar 2006
    Location
    Illinois, USA
    Posts
    12,164
    Thanks
    265
    Thanked 690 Times in 678 Posts

    Default

    Hm, I wonder if the fact that it's 65536-2 = 65534 is relevant. That is: it's exactly 2 less than 2^16. Maybe those bits line up in a certain way that includes all lower bits involving 2?

    Hmm... binary would be something like this:
    00010 = 2
    00100 = 4
    00110 = 6
    01000 = 8
    01010 = 10
    01100 = 12
    01110 = 14
    10000 = 16

    At 14, all bits are set except (the first* and) the last. In other words, this looks like it's allowing any and all 2-multiple value bits (that is: anything above the first '1' value bit), thereby requiring an even number is set.
    (*The first is irrelevant because it would be a higher number than necessary and there are always infinitely many more higher numbers available, so at some point you must stop.)

    Does that look correct to you? I'm still puzzled by it. But it's definitely a math trick that relies on how PHP does all of this (but I think it's a strategy used in C++ too, but I'm not positive about that).



    I feel like there should be a cleaner way to do this using the numeral '1' instead of '65534'. Remove those bits that match '1', rather than keeping only those that match '65534'.

    Aha... here it is:

    $a & ~1

    At least in theory I think that should work. Or something like it.
    Daniel - Freelance Web Design | <?php?> | <html>| español | Deutsch | italiano | português | català | un peu de français | some knowledge of several other languages: I can sometimes help translate here on DD | Linguistics Forum

  10. #10
    Join Date
    Mar 2005
    Location
    SE PA USA
    Posts
    30,495
    Thanks
    82
    Thanked 3,449 Times in 3,410 Posts
    Blog Entries
    12

    Default

    Yep, that ($a & ~1) seems to work:

    Code:
    $bigIndex = rand(0, (count($quotations) -1)) & ~1;
    It has the added advantage of nothing being out of range. Like:

    Code:
    $bigIndex = 65536 & 65534;
    is 0, while:

    Code:
    $bigIndex = 65536 & ~1;
    is 65536.

    Still doesn't explain why 65536 is out of range, though Unicode gives a clue on that.
    Last edited by jscheuer1; 07-27-2012 at 09:17 AM. Reason: detail
    - John
    ________________________

    Show Additional Thanks: International Rescue Committee - Donate or: The Ocean Conservancy - Donate or: PayPal - Donate

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •